@OneToMany @ManyToOne with composite
mtorrens Jun 21, 2006 6:46 AMI have a natural @ManyToMany relationship between Service and Deployment objects. Service objects have many Deployments. Deployment objects can be used by many Services. However, I haven't use a @ManyToMany because the relationship between the two objects has extra attributes, so I use an association table (ServiceDeployment).
The ServiceDeployment table has a composite key made from both serviceid and deploymentid.
When the ServiceDeployment table contains data about a Service, I can't delete the Service object. I get "Cannot delete or update a parent row: a foreign key constraint fails"
I think I need a JoinTable annotation on the @OneToMany and @ManyToOne relationships between Service and ServiceDeployment but I can't get the syntax right. Can someone please suggest the syntax for the @JoinTable annotation when a composite key is used.
Thanks in advance.
Three tables
CREATE TABLE `service` ( `serviceid` bigint(20) NOT NULL auto_increment, `name` varchar(255) NOT NULL default '', `version` bigint(20) default NULL, `description` varchar(255) default NULL, PRIMARY KEY (`serviceid`) ) CREATE TABLE `deployment` ( `deploymentid` bigint(20) NOT NULL auto_increment, `name` varchar(255) NOT NULL default '', `version` bigint(20) default NULL, PRIMARY KEY (`deploymentid`) ) CREATE TABLE `servicedeployment` ( `deploymentid` bigint(20) NOT NULL default '0', `serviceid` bigint(20) NOT NULL default '0', `pre` tinyint(1) default NULL, `post` tinyint(1) default NULL, PRIMARY KEY (`deploymentid`,`serviceid`), KEY `FK5A11633AE720A8AF` (`deploymentid`), KEY `FK5A11633A2157D23B` (`serviceid`), CONSTRAINT `FK5A11633A2157D23B` FOREIGN KEY (`serviceid`) REFERENCES `service` (`serviceid`), CONSTRAINT `FK5A11633AE720A8AF` FOREIGN KEY (`deploymentid`) REFERENCES `deployment` (`deploymentid`) )
ServiceDeploymentPK Class
@Embeddable
public class ServiceDeploymentPK implements Serializable
{
/* the pk fields */
private Long serviceId;
private Long deploymentId;
@Column( name = "serviceid" )
public Long getServiceId()
{
return this.serviceId;
}
public void setServiceId( Long serviceId )
{
this.serviceId = serviceId;
}
@Column( name = "deploymentid" )
public Long getDeploymentId()
{
return this.deploymentId;
}
public void setDeploymentId( Long deploymentId )
{
this.deploymentId = deploymentId;
}
...ServiceDeployment Class
@Entity
@Table(name = "servicedeployment")
public class ServiceDeployment implements Serializable
{
private static final long serialVersionUID = 589798996756500911L;
private ServiceDeploymentPK key;
private Boolean pre;
private Boolean post;
private Service service;
private Deployment deployment;
public ServiceDeployment()
{
}
@EmbeddedId
public ServiceDeploymentPK getKey()
{
return this.key;
}
public void setKey( ServiceDeploymentPK key )
{
this.key = key;
}
public Boolean getPre()
{
return pre;
}
public void setPre( Boolean pre )
{
this.pre = pre;
}
public Boolean getPost()
{
return post;
}
public void setPost( Boolean post )
{
this.post = post;
}
@ManyToOne
@JoinColumn(name = "serviceid", referencedColumnName = "serviceid", insertable = false, updatable = false)
public Service getService()
{
return service;
}
public void setService( Service service )
{
this.service = service;
}
@ManyToOne
@JoinColumn(name = "deploymentid", referencedColumnName = "deploymentid", insertable = false, updatable = false)
public Deployment getDeployment()
{
return deployment;
}
public void setDeployment( Deployment deployment )
{
this.deployment = deployment;
}
}Service Class
@Entity
@Table( name = "service" )
public class Service implements Serializable
{
private static final long serialVersionUID = -5735355220126370351L;
// Properties
private Long serviceId;
private Long version;
private String name;
private String description;
// One to Many
private Set<ServiceDeployment> serviceDeployments;
public Service()
{
}
@Id(generate = GeneratorType.AUTO)
@Column( name="serviceid" )
public Long getServiceId()
{
return serviceId;
}
public void setServiceId( Long serviceId )
{
this.serviceId = serviceId;
}
@Version
public Long getVersion()
{
return version;
}
public void setVersion( Long version )
{
this.version = version;
}
@Column( nullable=false )
public String getName()
{
return name;
}
public void setName( String name )
{
this.name = name;
}
@OneToMany
(
mappedBy="service",
cascade=CascadeType.ALL,
fetch=FetchType.EAGER
)
@org.hibernate.annotations.Cascade( value=org.hibernate.annotations.CascadeType.DELETE_ORPHAN )
public Set<ServiceDeployment> getServiceDeployments()
{
return serviceDeployments;
}
public void setServiceDeployments( Set<ServiceDeployment> serviceDeployments )
{
this.serviceDeployments = serviceDeployments;
}
}Deployment Class
@Entity
@Table( name = "deployment" )
public class Deployment implements Serializable
{
private static final long serialVersionUID = -7754844521569522001L;
// Properties
private Long deploymentId;
private Long version;
private String name;
// Children
private Set<ContextVariable> contextVariables;
// One to Many
private Set<ServiceDeployment> serviceDeployments;
public Deployment()
{
}
@Id(generate = GeneratorType.AUTO)
@Column( name="deploymentid" )
public Long getDeploymentId()
{
return deploymentId;
}
public void setDeploymentId( Long deploymentId )
{
this.deploymentId = deploymentId;
}
@Version
public Long getVersion()
{
return version;
}
public void setVersion( Long version )
{
this.version = version;
}
@Column( unique=true, length=255, nullable=false )
public String getName()
{
return name;
}
public void setName( String name )
{
this.name = name;
}
@OneToMany( mappedBy="deployment", cascade=CascadeType.ALL, fetch=FetchType.EAGER )
@org.hibernate.annotations.Cascade( value=org.hibernate.annotations.CascadeType.DELETE_ORPHAN )
@OrderBy("name ASC")
public Set<ContextVariable> getContextVariables()
{
return contextVariables;
}
public void setContextVariables( Set<ContextVariable> contextVariables )
{
this.contextVariables = contextVariables;
}
@OneToMany( mappedBy="deployment", cascade=CascadeType.ALL )
public Set<ServiceDeployment> getServiceDeployments()
{
return serviceDeployments;
}
public void setServiceDeployments( Set<ServiceDeployment> serviceDeployments )
{
this.serviceDeployments = serviceDeployments;
}
}