-->
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.  [ 12 posts ] 
Author Message
 Post subject: Two associations between two entities !
PostPosted: Thu Jan 24, 2008 8:41 pm 
Regular
Regular

Joined: Thu May 04, 2006 5:24 am
Posts: 55
Hi all,

I have relation between two classes like this:

|Class1| <>-[1]--------[*]-> |Class2|

and an annotation on the Class2 end @OneToMany(cascade=ALL),
but I have also one more association from Class1 to Class 2, like this:

|Class1| ------------------[1]-- |Class2|

So, in the Class1 instance, I have collection of Class2 instances (the first diagram), and also I have one another object of the Class2, which is the same as one of the elements in that collection (the second diagram).

But, when I fill Class1 object like this:

Code:
Class2 c = new Class2();
Class2 b = new Class2();
Class2 e = new Class2();

Set<Class2> list = new LinkedHashSet<Class2>();
list.add(c); list.add(b); list.add(e);

Class1 in = new Class1();

in.setList(list); <- this is related to the first diagram
in.setRef(c); <- this is related to the second diagram

hib.persist(in);



I got an error:

Code:
javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value: com.test.Class1.ref


It seems to me that it is trying firstly to get reference to c in databse, but because list of the objects is not yet writen (which containts c), it report this error. Do you maybe know how can I resolve this situation ?

I also tried to add @OneToOne annotations on the ref part (the second association) and it doesn't work.

Thanks in advance!


Top
 Profile  
 
 Post subject: Re: Two associations between two entities !
PostPosted: Fri Jan 25, 2008 1:32 pm 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
MilanMilanovich wrote:
|Class1| <>-[1]--------[*]-> |Class2|

and an annotation on the Class2 end @OneToMany(cascade=ALL)



What do you mean OneToMany on the Class2 side? The figure above suggests a ManyToOne association on the Class2 side. Show me the classes and their annotations.


Farzad-


Top
 Profile  
 
 Post subject: Re: Two associations between two entities !
PostPosted: Fri Jan 25, 2008 2:30 pm 
Regular
Regular

Joined: Thu May 04, 2006 5:24 am
Posts: 55
farzad wrote:
MilanMilanovich wrote:
|Class1| <>-[1]--------[*]-> |Class2|

and an annotation on the Class2 end @OneToMany(cascade=ALL)



What do you mean OneToMany on the Class2 side? The figure above suggests a ManyToOne association on the Class2 side. Show me the classes and their annotations.


Farzad-


Dear Farzad,

thank you very much on answers.

Not, it is ManyToOne association from Class2, but I wanted to say OneToMany from Class1 side to Class2 side (for list). Here is simplified code for my two classes:

Code:
@javax.persistence.Entity
public class Class1 implements java.io.Serializable {

   private Long id;

   private java.util.Set<Class2> classes = new java.util.HashSet<Class2>();

   private Class2 class2;

   public Class1() {

   }

   @javax.persistence.Id
   @javax.persistence.GeneratedValue
   public Long getId() {
      return this.id;
   }   

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


   @javax.persistence.OneToMany(mappedBy="class1", cascade=javax.persistence.CascadeType.ALL)
   public java.util.Set<Class2> getClasses() {
      return this.classes;
   }

   public void setClasses(java.util.Set<Class2> classes) {
      this.classes= classes;
   }   

   public Class2 getClass2() {
      return this.class2;
   }

   public void setClass2(Class2 class2) {
      this.class2 = class2;
   }   
}


@javax.persistence.Entity
public class Class2 java.io.Serializable {

   private Long id;

   private Class1 class1;

   public Class2() {
   }   

   @javax.persistence.Id
   @javax.persistence.GeneratedValue
   public Long getId() {
      return this.id;
   }   

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

   @javax.persistence.ManyToOne(optional=false)
   public Class1 getClass1() {
      return this.class1;
   }

   public void setClass1(Class1 class1) {
      this.class1 = class1;
   }
}


Top
 Profile  
 
 Post subject: Re: Two associations between two entities !
PostPosted: Fri Jan 25, 2008 10:26 pm 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
This is a circular kind of problem. Class2 needs to be saved before Class1 is saved since Class1 needs the primary key of Class2 and Class2 requires Class1 to be saved first since it is referencing Class1's primary key. I guess hibernate doesn't like this, but it is no surprise. I hope this explains the problem to you.


Farzad-


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 26, 2008 8:55 am 
Regular
Regular

Joined: Thu May 04, 2006 5:24 am
Posts: 55
Yes, I understand.

But I have composition on the Class1 side to Class2, so when I say persist(class1) it should save all Class2 elements in collecton (classes), together with class2, which ref to one of the Class2 elements in this collection. So, actually one Class2 element is reffered to two times, O.K. ?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 26, 2008 11:40 am 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
MilanMilanovich wrote:
Yes, I understand.

But I have composition on the Class1 side to Class2, so when I say persist(class1) it should save all Class2 elements in collecton (classes), together with class2, which ref to one of the Class2 elements in this collection. So, actually one Class2 element is reffered to two times, O.K. ?


No it is not ok. The one-to-many relation will not cascade and will wait for the in object to be saved. After that the objects in the set will be saved. However, at this point in is scheduled for saving. When it comes to the ref property hibernate has to save c before saving in and it cascades the save to c. At this point c has a pointer to in and it requires in to be saved before itself. So, it cascades back again to in but this time hibernate knows that in should be saved later so it returns but in still has no primary key and there the exception happens. I hope I didn't make it more confusing.


Farzad-


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 26, 2008 1:26 pm 
Regular
Regular

Joined: Thu May 04, 2006 5:24 am
Posts: 55
farzad wrote:
MilanMilanovich wrote:
Yes, I understand.

But I have composition on the Class1 side to Class2, so when I say persist(class1) it should save all Class2 elements in collecton (classes), together with class2, which ref to one of the Class2 elements in this collection. So, actually one Class2 element is reffered to two times, O.K. ?


No it is not ok. The one-to-many relation will not cascade and will wait for the in object to be saved. After that the objects in the set will be saved. However, at this point in is scheduled for saving. When it comes to the ref property hibernate has to save c before saving in and it cascades the save to c. At this point c has a pointer to in and it requires in to be saved before itself. So, it cascades back again to in but this time hibernate knows that in should be saved later so it returns but in still has no primary key and there the exception happens. I hope I didn't make it more confusing.


Farzad-


Dear Farzad,

thanks, so I need to save first c to database, but should I first add to it reference to Class1, like this: c.setClass1(in); ?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 26, 2008 1:27 pm 
Regular
Regular

Joined: Thu May 04, 2006 5:24 am
Posts: 55
farzad wrote:
MilanMilanovich wrote:
Yes, I understand.

But I have composition on the Class1 side to Class2, so when I say persist(class1) it should save all Class2 elements in collecton (classes), together with class2, which ref to one of the Class2 elements in this collection. So, actually one Class2 element is reffered to two times, O.K. ?


No it is not ok. The one-to-many relation will not cascade and will wait for the in object to be saved. After that the objects in the set will be saved. However, at this point in is scheduled for saving. When it comes to the ref property hibernate has to save c before saving in and it cascades the save to c. At this point c has a pointer to in and it requires in to be saved before itself. So, it cascades back again to in but this time hibernate knows that in should be saved later so it returns but in still has no primary key and there the exception happens. I hope I didn't make it more confusing.


Farzad-


Dear Farzad,

thanks, so I need to save first c to database, but should I first add to it reference to Class1, like this: c.setClass1(in); ?


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 27, 2008 2:18 pm 
Regular
Regular

Joined: Thu May 04, 2006 5:24 am
Posts: 55
Dear Farzad,

when I want to first persist ref (or class2), like this:

Code:
Class2 c = new Class2();
Class2 b = new Class2();
Class2 e = new Class2();

Set<Class2> list = new LinkedHashSet<Class2>();
list.add(c); list.add(b); list.add(e);

hib.persist(c); <- I GET AN ERROR HERE -> wich say: org.hibernate.PropertyValueException: not-null property references a null or transient value: com.test.Class2.class1.

Class1 in = new Class1();

in.setList(list); <- this is related to the first diagram
in.setRef(c); <- this is related to the second diagram

hib.persist(in);


I get and error, as I described in the code below. What can I do ?


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 27, 2008 3:21 pm 
Regular
Regular

Joined: Thu May 04, 2006 5:24 am
Posts: 55
Dear Farzad,

I found the way which works:

Code:
Class2 c = new Class2();
Class2 b = new Class2();
Class2 e = new Class2();

Set<Class2> list = new LinkedHashSet<Class2>();
list.add(c); list.add(b); list.add(e);

Class1 in = new Class1();

c.setClass1(in);
b.setClass1(in);
e.setClass1(in);

in.setList(list);
in.setRef(c);

hib.persist(in);


It works in this way, but the bad thing is that for every Class2 I must manually set Class1 reference, event that I define CascadeType.ALL on the Class1 side (for Class2 list).


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 27, 2008 3:44 pm 
Regular
Regular

Joined: Thu May 04, 2006 5:24 am
Posts: 55
farzad wrote:
MilanMilanovich wrote:
Yes, I understand.

But I have composition on the Class1 side to Class2, so when I say persist(class1) it should save all Class2 elements in collecton (classes), together with class2, which ref to one of the Class2 elements in this collection. So, actually one Class2 element is reffered to two times, O.K. ?


No it is not ok. The one-to-many relation will not cascade and will wait for the in object to be saved. After that the objects in the set will be saved. However, at this point in is scheduled for saving. When it comes to the ref property hibernate has to save c before saving in and it cascades the save to c. At this point c has a pointer to in and it requires in to be saved before itself. So, it cascades back again to in but this time hibernate knows that in should be saved later so it returns but in still has no primary key and there the exception happens. I hope I didn't make it more confusing.


Farzad-


Dear Farzad,

I have one question regarding your prevois explanation, when you say: "...When it comes to the ref property hibernate has to save c before saving in and it cascades the save to c...."

c is actually just one more reference to one of the elements in the collection which in element should save with cascade = ALL option. It should just link later c element to one of the saved elements in connection, it shouldn't save it, because there is not cascade or similar option ?


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 27, 2008 5:40 pm 
Regular
Regular

Joined: Thu May 04, 2006 5:24 am
Posts: 55
Dear Farzad,

I have rewritten this question in new topic, that should be clearer to reader and the most general: http://forum.hibernate.org/viewtopic.php?t=983251&start=0&postdays=0&postorder=asc&highlight=


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