-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: Bidirectional OneToMany with FK in EmbeddedId Inserts NULL
PostPosted: Mon Nov 20, 2006 11:40 am 
Newbie

Joined: Tue Mar 21, 2006 9:25 am
Posts: 8
Hibernate version: Core/Annotations/EM 3.2GA

The parent id of a child in a bidirectional child owned OneToMany collection is not set correctly when the parent id is part of the child's EmbeddedId and there is a duplicate parent mapping on the child.

For example, the following code results in the Parent being inserted OK, but the child inserted with a null value for PARENT_ID.

If however I shift the ManyToOne mapping from the Child to the ChildId in place of the duplicate mapping and change the Parent's mappedBy to "id.parent" as per [#ANN-381] it works OK. That's not a good work-around for me as it means the ChildIds have to contain the full Parent object which is undesirable as they are meant to be useful as lightweight place holders for the real child object.

As far as I'm aware the duplicate mapping should work so long as it is marked updateable/insertable=false.

Code:
@Embeddable
class ChildId implements Serializable {

   private Long parentId;

   @Column(name = "PARENT_ID", unique = false, nullable = false, insertable = true, updatable = true)
   public Long getParentId() {
      return this.parentId;
   }

   public void setParentId(Long parentId) {
      this.parentId = parentId;
   }

}

@Entity(name = "Child")
@Table(name = "CHILD")
class Child implements Serializable {

   private ChildId id;
   private Parent parent;

   @EmbeddedId
   public ChildId getId() {
      return this.id;
   }

   public void setId(ChildId id) {
      this.id = id;
   }

   @ManyToOne(optional = false, cascade = {}, fetch = FetchType.LAZY)
   @JoinColumn(name = "PARENT_ID", unique = false, nullable = false, insertable = false, updatable = false)
   public Parent getParent() {
      return parent;
   }

   public void setParent(Parent parent) {
      this.parent = parent;
   }

}

@Entity(name = "Parent")
@Table(name = "PARENT")
class Parent implements Serializable {

   private Long id;
   private Set<Child> children = new HashSet<Child>();

   @SequenceGenerator(name = "generator", allocationSize = 10, sequenceName = "PARENT_ID_SEQ")
   @Id
   @GeneratedValue(strategy = SEQUENCE, generator = "generator")
   @Column(name = "ID", unique = true, nullable = false, insertable = true, updatable = true)
   public Long getId() {
      return this.id;
   }

   public void setId(Long id) {
      this.id = id;
   }

   @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER, mappedBy = "parent")
   @Fetch(FetchMode.SUBSELECT)
   @Cascade( { org.hibernate.annotations.CascadeType.ALL, org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
   public Set<Child> getChildren() {
      return children;
   }

   public void setChildren(Set<Child> children) {
      this.children = children;
   }

}


Code:
EntityManager em = primaryEM();
Session session = (Session) em.getDelegate();
Transaction t = session.beginTransaction();
em.joinTransaction();

Parent parent = new Parent();
ChildId childId = new ChildId();
Child child = new Child();
child.setId(childId);
parent.getChildren().add(m);
child.setParent(parent);

em.persist(profile);
t.commit();


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 20, 2006 11:58 am 
Newbie

Joined: Tue Mar 21, 2006 9:25 am
Posts: 8
Typo correction:

parent.getChildren().add(m);

should read:

parent.getChildren().add(child);


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 21, 2006 10:59 am 
Newbie

Joined: Tue Mar 21, 2006 9:25 am
Posts: 8
Fixed. Went back to the Hibernate3.2 'cid' test code and found the following critical difference on Child:

Code:
   public void setParent(Parent parent) {
      this.parent = parent;
      this.getId().setParentId(parent.getId());
   }


I had been assuming Hibernate would spot the common column name between the duplicate parent mappings and take the value from the collection mapping and apply it to the simple mapping. It didn't occur to me that the above extra line of code would make a difference as it's an immutable type, but I guess Hibernate manages to find and replcae it anyway.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.