-->
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.  [ 5 posts ] 
Author Message
 Post subject: one-to-one cascade save to table with assigned id
PostPosted: Wed Aug 24, 2005 12:00 pm 
Expert
Expert

Joined: Wed Apr 06, 2005 5:03 pm
Posts: 273
Location: Salt Lake City, Utah, USA
Hibernate version: 3.1


I'm trying to create a one-to-one association on a foreign key (described in the docs here). I want to set cascade="all" for this association. If I set up the following mapping file and run the code below, I get an exception. OneToOneAssignedTable has an "identity" primary key, and a one-to-one association to AssignedIdTable, which has an "assigned" primary key.

If I just change the Id generator for AssignedIdTable to "identity" (or "native"), I don't get the exception, and everything saves fine (of course, I have to remove the line in the code that sets the Id).

It also works if I set OneToOneAssignedTable Id generator to "assigned", and AssignedIdTable to either "assigned" or "identity" (and appropriately change the code to set Ids properly).

The only combination that fails is if OneToOneAssignedTable has an "identity" Id, and AssignedIdTable has an "assigned" Id.

Am I trying to do something I shouldn't do? It seems like it has to be a bug, so I'm posting here to see if I can get some help. Thanks.

Mapping documents:

Code:
   <class
      name="OneToOneAssignedTable"
      table="onetooneassignedtable">

      <id
         name="Id"
         column="id"
         type="java.lang.Long">
         <generator class="native" />
      </id>

      <many-to-one
         name="AssignedIdTable"
         class="AssignedIdTable"
         unique="true"
         cascade="all">
         <column
            name="assignedidtable_id"
            not-null="true"
            unique="true" />
      </many-to-one>
   </class>

   <class
      name="AssignedIdTable"
      table="assignedidtable">

      <id
         name="AssignedIdTableId"
         column="assignedidtable_id"
         type="java.lang.Long">
         <generator class="assigned"/>
      </id>

   </class>


Code between sessionFactory.openSession() and session.close():

Code:
      AssignedIdTable aid = new AssignedIdTable();
      aid.setAssignedIdTableId(new Long(1));
      OneToOneAssignedTable otoa = new OneToOneAssignedTable();
      otoa.setAssignedIdTable(aid);
      
      Session s = openSession();
      Transaction t = s.beginTransaction();
      s.persist(otoa);
      t.commit();
      s.close();


Full stack trace of any exception that occurs:

Quote:
org.hibernate.PropertyValueException: not-null property references a null or transient value: org.hibernate.test.onetoone.cascade.OneToOneAssignedTable.AssignedIdTable
at org.hibernate.engine.Nullability.checkNullability(Nullability.java:72)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:265)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:167)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:101)
at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:131)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:87)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:38)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:582)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:560)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:564)
at org.hibernate.test.onetoone.cascade.OneToOneCascadeTest.testOneToOneCascadeAssigned(OneToOneCascadeTest.java:58)
at org.hibernate.test.TestCase.runTest(TestCase.java:140)


Name and version of the database you are using:

HSQL DB (also fails on SQL Server)

The generated SQL (show_sql=true):

Debug level Hibernate log excerpt:
Quote:
[junit] 09:30:42,609 DEBUG SessionImpl:270 - opened session at timestamp: 4607579924926464
[junit] 09:30:42,624 DEBUG JDBCTransaction:54 - begin
[junit] 09:30:42,624 DEBUG ConnectionManager:309 - opening JDBC connection
[junit] 09:30:42,624 DEBUG DriverManagerConnectionProvider:93 - total checked-out connections: 0
[junit] 09:30:42,624 DEBUG DriverManagerConnectionProvider:99 - using pooled JDBC connection, pool size: 0
[junit] 09:30:42,624 DEBUG JDBCTransaction:59 - current autocommit status: false
[junit] 09:30:42,624 DEBUG JDBCContext:207 - before transaction completion
[junit] 09:30:42,624 DEBUG AbstractSaveEventListener:461 - transient instance of: org.hibernate.test.onetoone.cascade.OneToOneAssignedTable
[junit] 09:30:42,624 DEBUG DefaultPersistEventListener:124 - saving transient instance
[junit] 09:30:42,624 DEBUG AbstractSaveEventListener:139 - saving [org.hibernate.test.onetoone.cascade.OneToOneAssignedTable#<null>]
[junit] 09:30:42,624 DEBUG AbstractSaveEventListener:221 - executing insertions
[junit] 09:30:42,624 DEBUG Cascade:237 - processing cascade ACTION_PERSIST for: org.hibernate.test.onetoone.cascade.OneToOneAssignedTable
[junit] 09:30:42,640 DEBUG CascadingAction:200 - cascading to persist: org.hibernate.test.onetoone.cascade.AssignedIdTable
[junit] 09:30:42,640 DEBUG IdentifierValue:153 - id unsaved-value strategy UNDEFINED
[junit] 09:30:42,655 DEBUG NonstrictReadWriteCache:39 - Cache lookup: org.hibernate.test.onetoone.cascade.AssignedIdTable#1
[junit] 09:30:42,655 DEBUG NonstrictReadWriteCache:46 - Cache miss
[junit] 09:30:42,655 DEBUG AbstractSaveEventListener:461 - transient instance of: org.hibernate.test.onetoone.cascade.AssignedIdTable
[junit] 09:30:42,655 DEBUG DefaultPersistEventListener:124 - saving transient instance
[junit] 09:30:42,655 DEBUG AbstractSaveEventListener:106 - generated identifier: 1, using strategy: org.hibernate.id.Assigned
[junit] 09:30:42,655 DEBUG AbstractSaveEventListener:139 - saving [org.hibernate.test.onetoone.cascade.AssignedIdTable#1]
[junit] 09:30:42,687 DEBUG Cascade:259 - done processing cascade ACTION_PERSIST for: org.hibernate.test.onetoone.cascade.OneToOneAssignedTable




(just for reference, I posted about this problem earlier, but have significantly narrowed down the problem now. previous post is here)


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 24, 2005 1:16 pm 
Beginner
Beginner

Joined: Tue Jun 28, 2005 4:33 pm
Posts: 21
I think I just ran into a similar problem, but after thinking about it, it makes sense.

An "assigned" generator means that you're telling hibernate that the application will take care of assigning the id. Even if you're trying to do a cascade save, hibernate will see the "assigned" generator type in the child and will not set it.

Depending on how you determine the value of your primary key, you might want to look into writing your own generator. Otherwise, if you use "assigned", you'll have to set it manually in all the classes, even if you use cascade all.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 24, 2005 1:31 pm 
Expert
Expert

Joined: Wed Apr 06, 2005 5:03 pm
Posts: 273
Location: Salt Lake City, Utah, USA
Thanks for the reply!

I'm not convinced, though, because I DID assign the Id before trying to save. I still think it should cascade the save. The objects are saveable, it's not like Hibernate can't save because of the assigned Id.

This is just a simple example that causes the exception. In my application, the "assigned" id is really a String UUID that we generate ourselves. So it needs to be "assigned".

Also, like I explained in the original post, if I change BOTH tables to have "assigned" Ids, it works. Also, if I run on a db that uses "sequence" instead of "identity" for the primary key, it also works! It has something to do with the identity insert logic in the cascade code that causes Hibernate not to realize that the object is not really transient because it's already in the queue to be saved.

I'm hoping someone from the Hibernate Team will take the time to try this out and tell me why it's not working.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 24, 2005 5:11 pm 
Beginner
Beginner

Joined: Mon Aug 15, 2005 4:37 pm
Posts: 27
Location: Washington DC
nathanmoon wrote:
Thanks for the reply!

I'm not convinced, though, because I DID assign the Id before trying to save. I still think it should cascade the save. The objects are saveable, it's not like Hibernate can't save because of the assigned Id.
.....
.


Nathan,

I think the FAQ's mention about mixing identifier strategies with identity generator.
http://www.hibernate.org/117.html#A8

Take a look at this and try the steps mentioned.
Hopefully this might help.

-Surya


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 24, 2005 5:19 pm 
Expert
Expert

Joined: Wed Apr 06, 2005 5:03 pm
Posts: 273
Location: Salt Lake City, Utah, USA
I'll look into that, but it sure looks like the answer at first glance. Thanks!


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