-->
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.  [ 11 posts ] 
Author Message
 Post subject: Best way to map @OneToOne association with generated keys
PostPosted: Tue Apr 11, 2006 8:23 pm 
Newbie

Joined: Tue Jul 20, 2004 1:25 pm
Posts: 12
Hibernate version:3.1.3
Hibernate Annotations version: 3.1beta9
Oracle version: 10.1.0.2.0

I'm trying to create a parent/child one-to-one association where the parent PK is generated by an oracle sequence. I want the child's FK to be set using the same sequence generated Id. The only way I've been able to get this to work is to create a bidirectional 1-to-1 mapping using the @GenericGenerator(strategy="foreign"...) annotation.

Questions...
1) Is there an ejb 3 "standard" way to do this without having to introduce the hibernate dependency?
2) is there a way to do this with a unidirectional 1-to-1 mapping?


Parent Class
Code:
@Entity
@Table(name="TblParent")
@SequenceGenerator(name="ParentSeq", sequenceName="PARENT_SEQ")
public class Parent
{
   private long _id;
   ...
   private Child _child;
   
   @Id
   @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="ParentSeq")
   public long getId()
   {
      return _id;
   }
   
   public void setId(long id)
   {
      _id = id;
   }
   
   @OneToOne(cascade=CascadeType.ALL)
   @PrimaryKeyJoinColumn
   public Child getChild()
   {
      return _child;
   }

   public void setChild(Child child)
   {
      _child = child;
   }
}


Child Class
Code:
@Entity
@Table(name="TblChild")
public class Child
{
   private long _id;
        ...
   private Parent _parent;
   
   @Id
   @GeneratedValue(generator="foreign")
   @GenericGenerator(name="foreign",strategy="foreign",parameters = {@Parameter(name="property", value="parent")})
   public long getId()
   {
      return _id;
   }
   
   public void setId(long id)
   {
      _id = id;
   }
   
   @OneToOne
   @PrimaryKeyJoinColumn
   public Parent getParent()
   {
      return _parent;
   }
   
   public void setParent(Parent parent)
   {
      _parent = parent;
   }



Session Persisting Code...
Code:
   Parent parent = new Parent();
   parent.setName("Parent");
      
   Child child = new Child();
   child.setName("Child");
   child.setParent(parent);
      
   parent.setChild(child);
   session.save(parent);



thanks,
Brett


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 12, 2006 3:34 am 
Newbie

Joined: Fri Mar 31, 2006 5:18 am
Posts: 9
To both points, no, at least I haven't found a way so far.

I don't have a sequence, but I do have a onetoone with the child taking on the parents key, and have found no way to do it that is either unidirectional (I presume you meant from parent to child) or ejb3 compliant.

So I have a solution that uses a bidirectional onetoone relation with the hibernate specific foreign key generator on the child entity. The reverse mapping is a private field on the child entity, so not exposed via the bean api.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 17, 2006 8:47 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Correct for both, this is not possible

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 25, 2006 12:33 pm 
Beginner
Beginner

Joined: Wed Apr 26, 2006 2:41 pm
Posts: 30
I hate to dredge this one out of the archives but... I've been using this pattern to map my OneToOne relationships (we're on Oracle and all of our sequences are generated).

Under certain use cases where the objects are getting created, I get the folowing exception. I've breakpointed it when it throws the excepton and both the parent entity and the child are both filled out. In our schema the productMaster is equivalent to the parent entity. Has anyone else seen tis error? Is there a way it could be seeing null when it has been filled out?


Code:
org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: productMaster
   at org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:44)
   at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:98)
   at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:165)
   at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:102)
   at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:689)
   at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:671)
   at org.hibernate.engine.CascadingAction$6.cascade(CascadingAction.java:156)
   at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:213)
   at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:157)
   at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:108)
   at org.hibernate.engine.Cascade.cascade(Cascade.java:248)
   at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:437)
   at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:173)
   at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:102)
   at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:689)
   at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:671)
   at org.hibernate.engine.CascadingAction$6.cascade(CascadingAction.java:156)
   at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:213)
   at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:157)
   at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:108)
   at org.hibernate.engine.Cascade.cascade(Cascade.java:248)
   at org.hibernate.event.def.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:412)
   at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:157)
   at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:102)
   at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:51)
   at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:679)
   at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:663)
   at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:667)
   at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:201)
   ... 27 more


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 25, 2006 3:17 pm 
Beginner
Beginner

Joined: Wed Apr 26, 2006 2:41 pm
Posts: 30
OK I was able to reproduce this in my code with a test case. It looks like having optional=true going from parent to child also required optional=false going in the other direction to fix.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 22, 2006 7:13 am 
Newbie

Joined: Fri Aug 11, 2006 8:40 am
Posts: 4
poswald wrote:
OK I was able to reproduce this in my code with a test case. It looks like having optional=true going from parent to child also required optional=false going in the other direction to fix.


Hello poswald,

what exactly do you mean by "optional=true". I am having the same problem and I am going mad finding a solution for this.

Thanks in advance


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 24, 2006 12:57 am 
Beginner
Beginner

Joined: Wed Apr 26, 2006 2:41 pm
Posts: 30
what I meant was this on the parent:
Code:
@PrimaryKeyJoinColumn
@OneToOne(cascade = CascadeType.ALL, fetch=FetchType.LAZY, optional=true)
public Child getChild() {
    return child;
  }

and this on the child:
Code:
@OneToOne(optional = false)
@PrimaryKeyJoinColumn
public Parent getParent() {
    return parent;
  }

I dont remember if that was the exact issue. This was a little while ago, but try that and let us know if it works for you too...


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 24, 2006 1:46 am 
Newbie

Joined: Fri Aug 11, 2006 8:40 am
Posts: 4
Hello,

thank you for the reply. Since I do not use annotations I cannot try your solution.

Kind regards


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 14, 2006 7:17 pm 
Newbie

Joined: Thu Sep 14, 2006 7:14 pm
Posts: 1
I fixed this issue by creating a new Parent on the child:
child.setParent(new Parent());


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 03, 2006 9:50 pm 
Newbie

Joined: Tue Oct 03, 2006 9:47 pm
Posts: 1
[If only i could delete a wrongly posted message]


Last edited by ndijkstra on Mon Oct 09, 2006 4:56 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 09, 2006 4:52 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
wrong forum

_________________
Emmanuel


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 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.