0 Replies Latest reply on Jun 21, 2006 6:46 AM by Mark Torrens

    @OneToMany @ManyToOne with composite

    Mark Torrens Newbie

      I 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;
       }
      
      
      }