[jboss-user] [EJB 3.0] - EJB 3.0 Persistence with Parent/Child and composite keys

jseriff do-not-reply at jboss.com
Thu Jan 3 17:09:34 EST 2008


I have a fairly common scenario which I am having trouble getting to work as I expect.  I have searched through the documentation and forums, but have not yet found any information which helped be with my issue.

I have two tables, lets call them PARENT and CHILD in a MySQL database.  


  | ------------------
  | | PARENT         |
  | ------------------
  | | PARENT_ID (PK) |
  | | <attributes>   |
  | ------------------
  | 
  | ------------------
  | | CHILD          |
  | ------------------
  | | PARENT_ID (PK) |
  | | CHILD_ID (PK)  |
  | | <attributes>   |
  | ------------------
  | 

I also have entity classes for these two tables -


  | @Entity
  | @Table(name="parent")
  | public class Parent implements Serializable {
  |     @Id 
  |     @GeneratedValue
  |     @Column(name="parent_id")
  |     private int parentId;
  | 
  |     @OneToMany(cascade={CascadeType.ALL})
  |     @JoinColumn(name="parent_id")
  |     private List<Child> children;
  | 
  |     //getters,setters,etc.
  | }
  | 
  | @Entity
  | @Table(name="child")
  | public class Child implements Serializable {
  |    @EmbeddedId
  |    private ChildId childId;
  | 
  |    //getters, setters, hashCode, equals, etc
  | }
  | 
  | @Embeddable
  | public class ChildId implements Serializable {
  |     @Column(name="parent_id")
  |     private int parentId;
  | 
  |     @Column(name="child_id")
  |     private int childId;
  | 
  |     //getters, setters, hashCode, equals, etc.
  | }
  | 

So far, this seems pretty straight forward, and I believe gives me what I want.

If I create a new Parent object, add child objects and merge, it appears to save, although in a strange fashion.  (Note: I am using merge, as in the general case, these may or may not be new objects).

The (paraphrased) SQL which is generated using hibernate is -


  | insert on PARENT.
  | insert on CHILD set PARENT_ID = 0 and CHILD_ID = <correct child_id>.
  | update on CHILD set PARENT_ID = <correct parent_id> and CHILD_ID = <correct child_id> where PARENT_ID = 0 and CHILD_ID = <correct child_id>
  | 

This does appear to get the job done, but I run into a major problem when I try to insert two parent_ids where child_id has the same value.  For example, if I have a Parent1 with a Child1 and a Child2 and a Parent2 with a Child2 (different object, same CHILD_ID) and a Child3 I get the following statements (paraphrased)-


  | insert on PARENT.
  | insert on PARENT.
  | insert on CHILD set PARENT_ID = 0 and CHILD_ID = 1
  | insert on CHILD set PARENT_ID = 0 and CHILD_ID = 2
  | insert on CHILD set PARENT_ID = 0 and CHILD_ID = 2 (not sure why this doesn't fail... i believe its done via a batch insert?)
  | insert on CHILD set PARENT_ID = 0 and CHILD_ID = 3
  | update on CHILD set PARENT_ID = 1 where PARENT_ID = 0 and CHILD_ID = 1
  | update on CHILD set PARENT_ID = 1 where PARENT_ID = 0 and CHILD_ID = 2
  | update on CHILD set PARENT_ID = 2 where PARENT_ID = 0 and CHILD_ID = 2
  | update on CHILD set PARENT_ID = 2 where PARENT_ID = 0 and CHILD_ID = 3
  | 

It then throws an exception because the update expected to change one row, and it changed none (the third update statement has no effect).

I am using JBoss 4.2 and SEAM 2.0 out of the box.

I am not clear what I am doing wrong.  I assume that the insert with parent_id is 0 is because there is no parent_id set on the child object.  I would also assume that the persistence manager would be responsible for setting this after the parent objects are inserted.

I would prefer not to have a backwards reference from the child object back to the parent object, as this seems redundant, and will never be used in this context.  Am I missing an annotation, or annotation parameter somewhere which will get me the expected behavior?  (I would expect to see only 2 parent and 4 child inserts, with no updates at all).  Am I forced to flush the persistence manager between each merge(parent) call?

Thanks for your help,
   Jason


View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4116880#4116880

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4116880



More information about the jboss-user mailing list