-->
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.  [ 9 posts ] 
Author Message
 Post subject: one-to-one and one-to-many for the same entity
PostPosted: Mon Dec 18, 2006 9:59 am 
Newbie

Joined: Mon Dec 18, 2006 9:07 am
Posts: 5
Hi all!

its possible to map a one-to-one relation and the same time mapping a one-to-many to the same entity? Or its a concetual error?

for example:

I have follow diagram:

Image


each 'MS' (Message) must have one 'SE' (Recipient). thats the 'fr' (from) relation.
in the same time I have tree other relations (1-N) from 'MS' to 'SE'. (to, cc and bcc relations)


my Message (MS) mapping:
Code:
     <class name="com.xyz.test.dorm.bean.Message">
        <id column="id_message" name="id">
            <generator class="increment"/>
        </id>
        <property name="sent"/>
        <property name="lastRetry"/>
        <property name="body"/>
        <property name="subject"/>
        <property name="retryCycle"/>
        <property name="retryThreshold"/>
        <property name="contentType"/>
        <property name="created"/>
        <one-to-one cascade="all-delete-orphan"
            class="com.xyz.test.dorm.bean.Recipient" name="from"/>
        <set cascade="all-delete-orphan" inverse="true" name="cc">
            <key column="ref_id_message"/>
            <one-to-many class="com.xyz.test.dorm.bean.Recipient"/>
        </set>
        <set cascade="all-delete-orphan" inverse="true" name="bcc">
            <key column="ref_id_message"/>
            <one-to-many class="com.xyz.test.dorm.bean.Recipient"/>
        </set>
        <set cascade="all-delete-orphan" inverse="true" name="to">
            <key column="ref_id_message"/>
            <one-to-many class="com.xyz.test.dorm.bean.Recipient"/>
        </set>
    </class>



and my Recipient.hbm.xml (SE)

Code:
    <class name="com.xyz.test.dorm.bean.Recipient">
        <id column="id_message" name="id">
            <generator class="foreign">
                <param name="property">message</param>
            </generator>
        </id>
        <property name="email"/>
        <property name="mediaType"/>
        <property name="name"/>
        <many-to-one cascade="save-update"
            class="com.zyx.test.dorm.bean.Message"
            column="ref_id_message" name="message"/>
    </class>


1st situation of test:
Code:
Message message = new Message();

Recipient recFrom = new Recipient();
recFrom.setName("Recipient FROM");
recFrom.setEmail("recipient.from@test.com");
recFrom.setMediaType(new Integer(0));
recFrom.setMessage(message);

Recipient recTo1 = new Recipient();
recTo1.setName("To1");
recTo1.setEmail("to1@test.com");
recTo1.setMediaType(new Integer(0));
recTo1.setMessage(message);

Recipient recCc1 = new Recipient();
recCc1.setName("Cc1");
recCc1.setEmail("cc1@teste.com");
recCc1.setMediaType(new Integer(0));
recCc1.setMessage(message);

Recipient recBcc1 = new Recipient();
recBcc1.setName("Bcc1");
recBcc1.setEmail("bcc1@test.com");
recBcc1.setMediaType(new Integer(0));
recBcc1.setMessage(message);

message.setFrom(recFrom);
message.addTo(recTo1);
message.addCc(recCc1);
message.addBcc(recBcc2);


and the error:

Code:
java.lang.Exception: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.xyz.test.dorm.bean.Recipient#7]



Ok. the cause (I think) its because all the Recipients relates to the same Message, and the 1-1 relation already done.

I change my class test.. I only set the setMessage for 1-1 relation.
follow my other test:
Code:
Message message = new Message();

Recipient recFrom = new Recipient();
recFrom.setName("Recipient FROM");
recFrom.setEmail("recipient.from@test.com");
recFrom.setMediaType(new Integer(0));
recFrom.setMessage(message);

Recipient recTo1 = new Recipient();
recTo1.setName("To1");
recTo1.setEmail("to1@test.com");
recTo1.setMediaType(new Integer(0));

Recipient recCc1 = new Recipient();
recCc1.setName("Cc1");
recCc1.setEmail("cc1@teste.com");
recCc1.setMediaType(new Integer(0));

Recipient recBcc1 = new Recipient();
recBcc1.setName("Bcc1");
recBcc1.setEmail("bcc1@test.com");
recBcc1.setMediaType(new Integer(0));

message.setFrom(recFrom);
message.addTo(recTo1);
message.addCc(recCc1);
message.addBcc(recBcc2);


only recFrom do setMessage...
but now, the new error is:
Code:
java.lang.Exception: org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: message


I think because each Recipient must have a reference of Message because 1-1 relation... but I cant do it because ocour the other error..

finally, is there a way to map this model (one-to-one and one-to-many to the same entity)?

thanks so much!

PS: sorry my english


Last edited by dbdbdb on Mon Dec 18, 2006 2:44 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 18, 2006 12:02 pm 
Beginner
Beginner

Joined: Tue Aug 29, 2006 8:13 pm
Posts: 32
Location: Spain (GU)
Hi,

About the last error (org.hibernate.id.IdentifierGenerationException), maybe I can help you if you tell me DBMS that are you using. I had problems with generator tag too. I ‘m using PostgreSQL.

About the first issue (org.hibernate.NonUniqueObjectException), I believe it’s a problem with lazy initialization. You should test the “lazy load”.

Above all, you had better change the model to improve the maintainability.

Regards,


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 18, 2006 1:02 pm 
Newbie

Joined: Mon Dec 18, 2006 9:07 am
Posts: 5
Javier Martinez wrote:
Hi,

About the last error (org.hibernate.id.IdentifierGenerationException), maybe I can help you if you tell me DBMS that are you using. I had problems with generator tag too. I ‘m using PostgreSQL.

About the first issue (org.hibernate.NonUniqueObjectException), I believe it’s a problem with lazy initialization. You should test the “lazy load”.

Above all, you had better change the model to improve the maintainability.

Regards,


Hi,

about the org.hibernate.id.IdentifierGenerationException exception, I dont know if is a generator tag problem.. but.. I use HSQLDB.

about the first error (org.hibernate.NonUniqueObjectException) i'm already use lazy load.. its default, is it?

thanks!!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 18, 2006 6:17 pm 
Beginner
Beginner

Joined: Tue Aug 29, 2006 8:13 pm
Posts: 32
Location: Spain (GU)
You should test different ways to generate the key. I advice to search in the documentation of your DBMS. I found it in PostgreSQl manual.

About the lazy load issue, sorry I wanted to say "lazy=false", with lazy=false, the problem could solve.

You are welcome!


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 19, 2006 6:52 am 
Newbie

Joined: Mon Dec 18, 2006 9:07 am
Posts: 5
Hi Javier Martinez. Thanks for help me!! =)

Maybe its a generator tag problem..
I tested with lazy="false" in all relations and the error persists...

My two classes relates like that:
Code:
Message  one-to-one Recipient ('from' attribute of Message)
Message one-to-many Recipient ('to' attribute of Message)
Message one-to-many Recipient ('cc' attribute of Message)
Message one-to-many Recipient ('bcc' attribute of Message)


so, to complete the one-to-one relation, I must have to set 'message.setFrom(recipient)' and recipient.setMessage(message)' ok?

right.
now.. I need to add somes 'To' recipients and 'Cc' and 'Bcc' too..
so, I do some like this:
message.addTo(recipient2);
message.addCc(recipient3);
message.addBcc(recipient4);

and finally, save the 'message':
session.saveOrUpdate(message);

and the error:
org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: message

IMHO, I think is because recipient2, recipient3 and recipient4 did not set the (must have) one-to-one relation (in this case, recipient2.setMessage(message).

so, why I did not set the 'setMessage' for all those recipients?
because if I set, I'll get the exception: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.xyz.test.dorm.bean.Recipient#1]
I think this exception ocours because the 'message' is already set with the 'from' message attribute.

But now, I dont know what I have to do...
if I set the all one-to-one relation, I get one exception... if not, I get another exception..

how to proceed in this case?

thanks so much!
and please, sorry for my very poor english...


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 19, 2006 7:23 am 
Newbie

Joined: Tue Dec 19, 2006 5:25 am
Posts: 9
Hi,

Maybe, the first error (IdentifierGenerationException: attempted to assign id from null one-to-one property: message) is more easy to resolve. ;-)

You should read the documentation of your DBMS (PostgrSQL, Oracle, etc.), and to search in hibernate integration. The syntax of generator tag depends on the DBMS. For instance, it is different between Oracle and PostgreSQL.

Don’t forget the credit system ;-)

Regards.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 19, 2006 7:54 am 
Newbie

Joined: Mon Dec 18, 2006 9:07 am
Posts: 5
Hi.
Thanks..

but doesnt work... :(
I really think the problem is not in the generator tag..
but.. I tested different ways to generate de id..

follow the modified mappings and new errors:

Message.hbm.xml
Code:
<hibernate-mapping>
    <class name="com.xyz.test.dorm.bean.Message">
        <id column="id_message" name="id">
            <generator class="identity"/>
        </id>
        <property name="sent"/>
        <property name="lastRetry"/>
        <property name="body"/>
        <property name="subject"/>
        <property name="retryCycle"/>
        <property name="retryThreshold"/>
        <property name="contentType"/>
        <property name="created"/>
        <one-to-one cascade="all-delete-orphan" lazy="false"
            class="com.xyz.test.dorm.bean.Recipient" name="from"/>
        <set cascade="all-delete-orphan" inverse="true" name="cc" lazy="false">
            <key column="ref_id_message_cc"/>
            <one-to-many class="com.xyz.test.dorm.bean.Recipient" />
        </set>
        <set cascade="all-delete-orphan" inverse="true" name="bcc" lazy="false">
            <key column="ref_id_message_bcc"/>
            <one-to-many class="com.xyz.test.dorm.bean.Recipient"/>
        </set>
        <set cascade="all-delete-orphan" inverse="true" name="to" lazy="false">
            <key column="ref_id_message_to"/>
            <one-to-many class="com.xyz.test.dorm.bean.Recipient"/>
        </set>
    </class>
</hibernate-mapping>


Recipient.hbm.xml
Code:
<hibernate-mapping>
    <class name="com.xyz.test.dorm.bean.Recipient">
        <id column="id_recipient" name="id">
            <generator class="identity"/>
        </id>
        <property name="mediaType"/>
        <property name="name"/>
        <property name="email"/>
        <one-to-one class="com.xyz.test.dorm.bean.Message"
            constrained="true" name="message" lazy="false"/>
        <many-to-one cascade="save-update" lazy="false"
            class="com.xyz.test.dorm.bean.Message"
            column="ref_id_message_to" name="messageTo"/>
        <many-to-one cascade="save-update" lazy="false"
            class="com.xyz.test.dorm.bean.Message"
            column="ref_id_message_cc" name="messageCc"/>
        <many-to-one cascade="save-update" lazy="false"
            class="com.xyz.test.dorm.bean.Message"
            column="ref_id_message_bcc" name="messageBcc"/>
    </class>
</hibernate-mapping>


new error:
org.hibernate.PropertyValueException: not-null property references a null or transient value: com.xyz.test.dorm.bean.Recipient.message

I really think this error is because if I have one-to-one relation.. I must have set the assissiation...

thanks


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 19, 2006 2:34 pm 
Beginner
Beginner

Joined: Tue Aug 29, 2006 8:13 pm
Posts: 32
Location: Spain (GU)
Have you ever tested to create different objects Message for each Recipient?, something like that (sorry for the errors, but it’s really difficult to write code without Eclipse) :

Message message = new Message();

Recipient recFrom = new Recipient();
recFrom.setName("Recipient FROM");
recFrom.setEmail("recipient.from@test.com");
recFrom.setMediaType(new Integer(0));
recFrom.setMessage(message);

Message message2 = new Message();
Recipient recTo1 = new Recipient();
recTo1.setName("To1");
recTo1.setEmail("to1@test.com");
recTo1.setMediaType(new Integer(0));
recFrom.setMessage(message2);

Message message3 = new Message();
Recipient recCc1 = new Recipient();
recCc1.setName("Cc1");
recCc1.setEmail("cc1@teste.com");
recCc1.setMediaType(new Integer(0));
recFrom.setMessage(message3);

Message message4 = new Message();
Recipient recBcc1 = new Recipient();
recBcc1.setName("Bcc1");
recBcc1.setEmail("bcc1@test.com");
recBcc1.setMediaType(new Integer(0));
recFrom.setMessage(message4);

message.setFrom(recFrom);
message.addTo(recTo1);
message.addCc(recCc1);
message.addBcc(recBcc2);


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 20, 2006 8:52 am 
Newbie

Joined: Mon Dec 18, 2006 9:07 am
Posts: 5
Hi!
your post did not resolve directly my problem.. but, with you post I have one idea that resolve my problem (not 100% yet)! :)

I mapped like that my model:

Message.hbm.xml
Code:
<class name="com.xyz.test.dorm.bean.Message">
        <id column="id_message" name="id">
            <generator class="identity"/>
        </id>
        <property name="sent"/>
        <property name="lastRetry"/>
        <property name="body"/>
        <property name="subject"/>
        <property name="retryCycle"/>
        <property name="retryThreshold"/>
        <property name="contentType"/>
        <property name="created"/>
      
        <many-to-one cascade="all-delete-orphan"
         name="from" class="com.xyz.test.dorm.bean.Recipient"
         column="ref_id_message_from" UNIQUE="TRUE"/>
      
      
        <set cascade="all-delete-orphan" inverse="true" name="cc" >
            <key column="ref_id_message_cc"/>
            <one-to-many class="com.xyz.test.dorm.bean.Recipient" />
        </set>
        <set cascade="all-delete-orphan" inverse="true" name="bcc" >
            <key column="ref_id_message_bcc"/>
            <one-to-many class="com.xyz.test.dorm.bean.Recipient"/>
        </set>
        <set cascade="all-delete-orphan" inverse="true" name="to">
            <key column="ref_id_message_to"/>
            <one-to-many class="com.xyz.test.dorm.bean.Recipient"/>
        </set>
    </class>


Recipient.hbm.xml
Code:
    <class name="com.xyz.test.dorm.bean.Recipient">
        <id column="id_recipient" name="id">
            <generator class="identity">
            </generator>
        </id>
        <property name="mediaType"/>
        <property name="name"/>
        <property name="email"/>
      
      <one-to-one name="messageFrom" class="com.xyz.test.dorm.bean.Message"
         PROPERTY-REF="from" />
      
        <many-to-one cascade="all-delete-orphan"
            class="com.xyz.test.dorm.bean.Message"
            column="ref_id_message_to" name="messageTo"/>
        <many-to-one cascade="all-delete-orphan"
            class="com.xyz.test.dorm.bean.Message"
            column="ref_id_message_cc" name="messageCc"/>
        <many-to-one cascade="all-delete-orphan"
            class="com.xyz.test.dorm.bean.Message"
            column="ref_id_message_bcc" name="messageBcc"/>
      
    </class>


and my code:
Test.java
Code:
      Message message = new Message();
      
      Recipient recFrom = new Recipient();
      recFrom.setName("Some Recipient");
      recFrom.setEmail("fromtest@test.com");
      recFrom.setMediaType(new Integer(0));
      
      Recipient recTo1 = new Recipient();
      recTo1.setName("To1");
      recTo1.setEmail("some-email@test.com");
      recTo1.setMediaType(new Integer(0));
      
      Recipient recTo2 = new Recipient();
      recTo2.setName("To2");
      recTo2.setEmail("some-email@test.com");
      recTo2.setMediaType(new Integer(0));
      
      Recipient recCc1 = new Recipient();
      recCc1.setName("Cc1");
      recCc1.setEmail("some-email@test.com");
      recCc1.setMediaType(new Integer(0));
      
      Recipient recCc2 = new Recipient();
      recCc2.setName("Cc2");
      recCc2.setEmail("some-email@test.com");
      recCc2.setMediaType(new Integer(0));
      
      Recipient recBcc1 = new Recipient();
      recBcc1.setName("Bcc1");
      recBcc1.setEmail("some-email@test.com");
      recBcc1.setMediaType(new Integer(0));
      
      Recipient recBcc2 = new Recipient();
      recBcc2.setName("Bcc2");
      recBcc2.setEmail("some-email@test.com");
      recBcc2.setMediaType(new Integer(0));
      
      message.setFrom(recFrom);
      recFrom.setMessageFrom(message);
      
      message.addTo(recTo1);
      recTo1.setMessageTo(message);
      
      message.addTo(recTo2);
      recTo2.setMessageTo(message);
      
      message.addCc(recCc1);
      recCc1.setMessageCc(message);
      
      message.addCc(recCc2);
      recCc2.setMessageCc(message);
      
      message.addBcc(recBcc1);
      recBcc1.setMessageBcc(message);
      
      message.addBcc(recBcc2);
      recBcc2.setMessageBcc(message);
      
      
      message.setSubject("Test");
      message.setBody("Body of the message");
      message.setContentType("text/plain");
      message.setRetryCycle("5d");
      message.setRetryThreshold(new Integer(5));
      message.setCreated(new Date());
      message.setSent(new Date());
      message.setLastRetry(new Date());
      
      
      session.saveOrUpdate(message);


And finally my new Message with new Recipient are save and simply recoreved!!

thanks a lot Javier!! really thanks! =)

now.. I'll search why I cant save a new Message using Recipients loaded from DB without a org.hibernate.exception.ConstraintViolationException: could not insert: [com.xyz.test.dorm.bean.Message]

follow my code that throwed this exception:
Code:
      Message msg = new Message();
      Recipient rFrom = (Recipient) session.load(Recipient.class, new Integer(1));
      Recipient rTo1 = (Recipient) session.load(Recipient.class, new Integer(5));
      
      msg.setSubject("fsdfasdfsadfasfasdfsdfasdf");
      msg.setFrom(rFrom);
      rFrom.setMessageFrom(msg);
      
      msg.addTo(rTo1);
      rTo1.setMessageTo(msg);
      
      session.saveOrUpdate(msg);


but this error happens now.. and I did not search about this yet..
I think is because the Recipient that I retrivied from DB are already associate with other Message.. may only disassociate resolve this problem... I will try and post again!

Thanks!!


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