1 Reply Latest reply on Oct 17, 2008 1:24 AM by mark_man

    OneToMany and composite primary key containing foreign key

    amayingenta

      Perhaps I'm being dumb, but none of the replies in similar threads have helped me get my head around this... I'm using JBoss 4.0.4RC1.

      I want to have a parent-child relationship where the child PK is a composite PK where the first part is the parent id. I want to avoid having a join table, or a separate unique id on the child.

      Ideally in the object model I would like a uni-directional relationship, but the spec suggests that will use a join table, so I'm trying a bi-directional relationship instead.

      @Entity
      public class Parent implements Serializable
      {
       @Id @GeneratedValue
       private Integer id;
       @OneToMany(targetEntity=Child.class, mappedBy="parent", fetch=FetchType.EAGER, cascade=CascadeType.ALL)
       private Set<Child> children;
      
       // snip - getters and setters
      }
      
      @Entity
      @IdClass(ChildPk.class)
      public class Child implements Serializable
      {
       @Id private Integer parentId;
       @Id private String name;
       private String value;
       @ManyToOne @JoinColumn(name="parentId", referencedColumnName="id", updatable=false, insertable=false)
       private Parent parent;
      
       // snip - getters and setters
      }
      


      This deploys and the tables and foreign key are correct, but when I try to persist a Parent with a single child, where the Parent id is null and the Child parentId is null I get a BatchUpdateException. I suspect that this is because it is trying to insert null into Child.parentId. (I had made sure to add the Child to the children collection, and set the parent on the Child).

      Without the updatable=false, insertable=false on the @JoinColumn this won't deploy because of a duplicate parentId column - I tried putting the updatable=false, insertable=false in a @Column annotation on the parentId field, but that didn't work so I put it on the @JoinColumn instead - but I can see why that might cause parentId to be considered separately from the relationship and not get the foreign key automatically populated.

      So, I have a few questions:

      * Are relationships like this supported in EJB3 (as spec'd) or the JBoss implementation? The spec seems a bit vague about this.

      * Should I expect foreign keys to be automatically populated? And is that affected by having an auto-generated id on the other end of the relationship?

      * Am I using @IdClass correctly? It seems odd to never have an instance of ChildPk in my Child object. Would @EmbeddedId work any differently?

      * Is there a simple way to make this work? (I guess that's the biggie!)

      In this simple case I could probably use the hibernate @CollectionOfElements (I've not tried it), but I'd rather stick with the EJB3 annotations for portability.

      Answers appreciated, as this probably determines whether we use EJB3 for an upcoming project.

      Thanks,
      Andrew