-->
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: Cascade save and Unidirectional navigability - FK not null
PostPosted: Sun Aug 01, 2004 11:01 pm 
Regular
Regular

Joined: Thu Jul 01, 2004 12:13 am
Posts: 68
Location: San Diego, CA
I have run into an issue where I would like to force navigability a certain way per our requirements. I do this as follows: Table A is a parent of Table B and B has a FK to A that is set to NOT NULL. This is a 1:M relationship respectively.

In Hibernate, I have Object A with a Set of B's and inverse set implicitly to the default of "FALSE". In Object B, I have no reference to A (i.e., no <many-to-one>) so I force access only through object A. Thus preventing any circular references.

While I know Hibernate supports unidirectional navigability by default, it seems to require that the foreign keys in these tables be set to nullable. This is usually quite impossible to convince a DBA to do that because referential integrity.

When I try to run as such, I get a FK Constraint violation, as expected, saying the key cannot be NULL. Because I have cascade=all, I see the INSERT INTO for Table A and Table B. When I pull the constraint off I see the two inserts again followed by an UPDATE to update the FK.

I was wondering what are my options here considering that the FK must be NOT NULL. It is requirement that I don't have a reference to Object A in Object B to prevent the circular reference because we need to be able to serialize the object without recursion.

TIA,
Lou


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 02, 2004 3:43 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
This is a FAQ, again. You mentioned on JIRA that you have Hibernate in Action. There is an excellent explanation in chapter 6. Please read it.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 02, 2004 2:17 pm 
Regular
Regular

Joined: Thu Jul 01, 2004 12:13 am
Posts: 68
Location: San Diego, CA
christian wrote:
This is a FAQ, again. You mentioned on JIRA that you have Hibernate in Action. There is an excellent explanation in chapter 6. Please read it.


Do you mean this FAQ? :

Quote:
I'm using a one-to-many association with a NOT NULL constraint on the key column and Hibernate causes constraint violations.

Use a bidirectional association, mapping the many-valued end with inverse="true".


Also, you reiterate this in your book as well.

Quote:
In a unidirectional one-to-many association, the foreign key column CATEGORY_ID in the ITEM must be nullable. An Item could be saved without knowing anything about a Category


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 02, 2004 2:20 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
There is not much left to explain, I guess. If you say "NOT NULL", you say "requires a reference". If you don't want that reference, don't say NOT NULL. There is no magic that will help here.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 02, 2004 2:22 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Oh, and if your serialization can't handle circular references, you already know where the problem is in your case. I suggest fixing this.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 02, 2004 2:53 pm 
Regular
Regular

Joined: Thu Jul 01, 2004 12:13 am
Posts: 68
Location: San Diego, CA
christian wrote:
There is not much left to explain, I guess. If you say "NOT NULL", you say "requires a reference". If you don't want that reference, don't say NOT NULL. There is no magic that will help here.


Thanks for confirming my understanding here...I was looking for some vodoo here! ;o) And yes, we're looking at the XML Serialization as well. Just looking at approaches from all angles.

I do have one last question and then I'll put this to rest. I have cascade save-update set up on the Set of children in the parent with a unidirectional relationship set-up and the FK as nullable. When I save a brand new parent that has a brand new child in its Set, I see the log below when I have debug on and the records persist successfully.

Hibernate makes the INSERT INTO to my parent, then INSERT INTO into my child, and then an UPDATE on the child to update the FK in the child table? Here's where I was looking for the vodoo magic where Hibernate could somehow dynamically combine the latter INSERT INTO and UPDATE into one statement, thus fullfilling the NOT NULL constraint on the FK.

I understand what you're saying about NOT NULL equaling defined reference, and I can live with that, but some vodoo to add the key behind the scenes would be cool too! That's the essence of my JIRA request.

Again thanks,
Lou


Code:
11:37:54,733 DEBUG SQL:237 - insert into CLM_CLAIM (TCN, LAW_ENFORCEMENT_FLAG, EPD_ORG_USER_ID, UPDATED_BY, CO_CD, UPDATED_DT, CLAIM_PROPERTY_FLAG, ARCHIVE_FLAG, CLAIM_NUMBER, CREATED_DT, CREATED_BY, FRAUD_INV_FLAG, POLICY_NUMBER, CLAIM_SENSITIVITY_FLAG, CLAIM_SENSITIVITY_CATEGORY, EPD_ORG_ID, WITNESS_FLAG, CLAIM_MEMO, SET_FOR_AUDIT, ARCHIVE_DATE, INJURED_FLAG, LOSS_EVENT_ID, CLAIM_STATUS_CD, CLAIM_ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
11:37:54,733 DEBUG BatcherImpl:241 - preparing statement
11:37:54,733 DEBUG EntityPersister:388 - Dehydrating entity: [com.mitchell.services.technical.claim.dao.vo.ClmClaim#240]
11:37:54,733 DEBUG LongType:46 - binding '0' to parameter: 1
11:37:54,733 DEBUG StringType:46 - binding 'F' to parameter: 2
11:37:54,733 DEBUG IntegerType:46 - binding '1234' to parameter: 3
11:37:54,748 DEBUG StringType:46 - binding 'lsacco' to parameter: 4
11:37:54,748 DEBUG StringType:46 - binding 'JH' to parameter: 5
11:37:54,748 DEBUG TimestampType:46 - binding '02 August 2004 11:37:48' to parameter: 6
11:37:54,748 DEBUG StringType:46 - binding 'Y' to parameter: 7
11:37:54,748 DEBUG StringType:46 - binding 'Y' to parameter: 8
11:37:54,748 DEBUG StringType:46 - binding '84642004' to parameter: 9
11:37:54,748 DEBUG TimestampType:46 - binding '02 August 2004 11:37:48' to parameter: 10
11:37:54,764 DEBUG StringType:46 - binding 'lsacco' to parameter: 11
11:37:54,764 DEBUG StringType:46 - binding 'F' to parameter: 12
11:37:54,764 DEBUG StringType:46 - binding '123897034ASDF' to parameter: 13
11:37:54,764 DEBUG StringType:46 - binding 'F' to parameter: 14
11:37:54,764 DEBUG StringType:41 - binding null to parameter: 15
11:37:54,764 DEBUG IntegerType:46 - binding '235' to parameter: 16
11:37:54,764 DEBUG StringType:46 - binding 'T' to parameter: 17
11:37:54,764 DEBUG StringType:46 - binding 'Hello Der' to parameter: 18
11:37:54,764 DEBUG StringType:46 - binding 'F' to parameter: 19
11:37:54,764 DEBUG TimestampType:46 - binding '02 August 2004 11:37:48' to parameter: 20
11:37:54,764 DEBUG StringType:46 - binding 'F' to parameter: 21
11:37:54,764 DEBUG LongType:41 - binding null to parameter: 22
11:37:54,764 DEBUG Cascades:341 - id unsaved-value strategy NULL
11:37:54,764 DEBUG StringType:46 - binding 'open' to parameter: 23
11:37:54,764 DEBUG LongType:46 - binding '240' to parameter: 24
11:37:54,764 DEBUG BatcherImpl:28 - Adding to batch
11:37:54,780 DEBUG EntityPersister:453 - Inserting entity: [com.mitchell.services.technical.claim.dao.vo.ClmClaimExposure#166]
11:37:54,780 DEBUG EntityPersister:454 - Version: 0
11:37:54,780 DEBUG BatcherImpl:50 - Executing batch size: 1
11:37:54,811 DEBUG BatcherImpl:58 - success of batch update unknown: 0
11:37:54,811 DEBUG BatcherImpl:203 - done closing: 0 open PreparedStatements, 0 open ResultSets
11:37:54,811 DEBUG BatcherImpl:261 - closing statement
11:37:54,826 DEBUG BatcherImpl:196 - about to open: 0 open PreparedStatements, 0 open ResultSets
11:37:54,826 DEBUG SQL:237 - insert into CLM_CLAIM_EXPOSURE (TCN, EPD_ORG_USER_ID, CO_CD, UPDATED_BY, UPDATED_DT, EXPOSURE_NUMBER, CLAIM_NUMBER, CREATED_BY, CREATED_DT, EPD_ORG_ID, CWQ_CLM_WORK_QUEUE_ID, DESCRIPTION_OF_WHAT_HAPPENED, TOTAL_CLAIM_EXPOSURE_AMOUNT, SET_1_SETTLEMENT_ID, DEDUCTIBLE_AMOUNT, DATE_OF_LOSS, CLM_VEH_CLAIM_VEHICLE_ID, LOSS_TYPE, POLICY_COVERAGE_ID, COVERAGE_TYPE_CODE, CLAIM_EXPOSURE_ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
11:37:54,826 DEBUG BatcherImpl:241 - preparing statement
11:37:54,826 DEBUG EntityPersister:388 - Dehydrating entity: [com.mitchell.services.technical.claim.dao.vo.ClmClaimExposure#166]
11:37:54,826 DEBUG LongType:46 - binding '0' to parameter: 1
11:37:54,826 DEBUG IntegerType:46 - binding '1234' to parameter: 2
11:37:54,826 DEBUG StringType:46 - binding 'JH' to parameter: 3
11:37:54,826 DEBUG StringType:46 - binding 'lsacco' to parameter: 4
11:37:54,826 DEBUG TimestampType:46 - binding '02 August 2004 11:37:48' to parameter: 5
11:37:54,826 DEBUG StringType:46 - binding '1684641988' to parameter: 6
11:37:54,826 DEBUG StringType:46 - binding '84642004' to parameter: 7
11:37:54,826 DEBUG StringType:46 - binding 'lsacco' to parameter: 8
11:37:54,826 DEBUG TimestampType:46 - binding '02 August 2004 11:37:48' to parameter: 9
11:37:54,826 DEBUG IntegerType:46 - binding '235' to parameter: 10
11:37:54,826 DEBUG IntegerType:46 - binding '1' to parameter: 11
11:37:54,826 DEBUG StringType:46 - binding 'This guy just crashed into me' to parameter: 12
11:37:54,826 DEBUG BigDecimalType:46 - binding '5000' to parameter: 13
11:37:54,826 DEBUG IntegerType:46 - binding '123' to parameter: 14
11:37:54,826 DEBUG BigDecimalType:46 - binding '500' to parameter: 15
11:37:54,842 DEBUG TimestampType:46 - binding '02 August 2004 11:37:48' to parameter: 16
11:37:54,842 DEBUG LongType:41 - binding null to parameter: 17
11:37:54,842 DEBUG StringType:41 - binding null to parameter: 18
11:37:54,842 DEBUG LongType:41 - binding null to parameter: 19
11:37:54,842 DEBUG StringType:41 - binding null to parameter: 20
11:37:54,842 DEBUG LongType:46 - binding '166' to parameter: 21
11:37:54,842 DEBUG BatcherImpl:28 - Adding to batch
11:37:54,951 DEBUG BasicCollectionPersister:508 - Inserting collection: [com.mitchell.services.technical.claim.dao.vo.ClmClaim.exposureSet#240]
11:37:54,951 DEBUG BatcherImpl:196 - about to open: 0 open PreparedStatements, 0 open ResultSets
11:37:54,951 DEBUG SQL:237 - update CLM_CLAIM_EXPOSURE set CLA_CLAIM_ID=? where CLAIM_EXPOSURE_ID=?
11:37:54,951 DEBUG BatcherImpl:241 - preparing statement
11:37:54,951 DEBUG LongType:46 - binding '240' to parameter: 1
11:37:54,951 DEBUG LongType:46 - binding '166' to parameter: 2


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 02, 2004 2:55 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
You have all the resource to understand what a "standalone entity" is, please read the book again if you still don't see why Hibernate can not just save a B entity with a foreign key filled in when all you have is an A with a set of Bs.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 02, 2004 3:07 pm 
Regular
Regular

Joined: Thu Jul 01, 2004 12:13 am
Posts: 68
Location: San Diego, CA
Totally agree, but how about if you knew that it was being navigated to or created with a Parent at runtime?

Lou


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 02, 2004 3:08 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
We don't. It would also violate almost all principles of a consistent data model if we would allow this. Believe me, the behavior and the model is correct in every aspect. Your expectations are not.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 04, 2005 12:55 pm 
Newbie

Joined: Fri Mar 04, 2005 2:02 pm
Posts: 18
In testing it seems that setting not-null="true" AND update="false" on the Parent set/bag/etc in a uni-directional one-to-many gives the behavior of two inserts where the child insert has the FK set.

This gives the output that a lot of people ask for with unidir one-to-many.

What would the drawback be with using these two parameters on a collection?

Thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 17, 2008 3:26 pm 
Newbie

Joined: Thu May 31, 2007 3:27 am
Posts: 11
I have this situation also in my model, where A is parent to B in a one-to-many bidirectional relation. Even if in your case, there is no object relation between B and its parent A, it is the same situation since your using a "inverse=true".

The whole problem come with the cascade="all" which make all inserts on the child objects before the parent object, so child objects are created and tries to reference a parent that has not been created yet.

It would work if the parent was saved first, I don't know exactly why it is not like that. Maybe some other problems would occur if that was the case.

So to "fix" this, I save the parent object before adding child objects, all this in the same transaction, so it doesn't look too strange.

Code:
Transaction tx=session.beginTransaction();
Parent parent=new Parent();
parent.setName("a parent name");
parent.setDescription("a parent description");
session.save(parent);
parent.addChild(new Child()); //addChild method call child.setParent(this)
tx.commit();


In the method child.setParent(Parent p), you could add some runtime validation that ensure that the parent has an id, so it exists.


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.