-->
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: Weird insert error with foreign key relationship
PostPosted: Wed Dec 10, 2003 5:14 pm 
Beginner
Beginner

Joined: Tue Sep 02, 2003 12:15 pm
Posts: 33
Basically, here is the problem. I have a business process which I wrap in a transaction. I am using the hibernate transaction management for this. There are 4 separate hibernate types that are inserted.
1. Header
2. Batch
3. AchTransaction
4. AchAddendem

The header is the only one without a fk relationship. The batch has a relationship to the header, the transaction to the batch, and the addendem to the transaction. All of the objects except the Header use a native serial id generated by the database as the id. The header uses an assigned id. When I insert the header, then start inserting batches from within the transaction, I get an error saying that I'm breaking the fk relationship between the Batch and Header(Header record 1248BB doesn't exist). If I insert the header before I begin the transaction, everything runs smoothly. I'm not sure how hibernate caches the statements until it flushes or how it checks from within the transaction to see if a particular foreign key constraint exists or not. All I know is it seems to see my foreign key constraints which are all being created inside the same transaction in 3 out of 4 tables.

I tried setting my key up like this and neither seemed to make a difference.

<composite-id name="key" class="my.header.Key">
<key-property name="achHeader" column="ach_header" type="string"/>
</composite-id>

<id name="achHeader" column="ach_header" type="string">
<generator class="assigned"/>
</id>

I can also see in the debug statements they the id's from the header and the batch are identical.

Any suggestions?

Thanks

Nic


Top
 Profile  
 
 Post subject: Forgot 1 item.
PostPosted: Wed Dec 10, 2003 5:24 pm 
Beginner
Beginner

Joined: Tue Sep 02, 2003 12:15 pm
Posts: 33
The component is mapped inside the Batch like this.

<component name="achHeader" class="my.header.Key">
<property name="achHeader" column="ach_header" type="string">
</component>

This is also the same way the other classes are mapped to their fk counterparts.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 10, 2003 6:00 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
That's a little confuse to me. Can you follow instructions in http://www.hibernate.org/ForumMailinglists/HowToAskForHelp to describe your case. The infos you giva are notcomplete enough

I suspect you're mismatching component and relationship, but I don't really know

_________________
Emmanuel


Top
 Profile  
 
 Post subject: Additional information
PostPosted: Wed Dec 10, 2003 6:32 pm 
Beginner
Beginner

Joined: Tue Sep 02, 2003 12:15 pm
Posts: 33
I have attached some of the logs as well as the mapping files. I will try to give you more of a scenario.

Scenario 1

get Session
begin transaction
1. Insert a header record.
2. Insert 1200 Batch records.
3. Insert 500 Transaction records.
4. Insert 500 Addendem records.
commit transaction.

This scenario goes to the first step of #2 throwing the exception shown below in the logs.

--------------------------------------------------------------------------------------

Scenario 2

get Session
1. Insert a header record.
flush Session

get Session
begin transaction
2. Insert 1200 Batch records.
3. Insert 500 Transaction records.
4. Insert 500 Addendem records.
commit transaction.

This scenario works. I'm just not sure why.


----------- Begin debug log ------------------------


113055 DEBUG [RMI TCP Connection(1)-10.1.21.36]

Here is where I insert the header record.

impl.SessionImpl - saving [com.tab.core.shared.vo.MC_AchHeader#com.tab.core.shared.vo.MC_AchHeaderPK {achHeader='1011243846576910001340312090342Z'}]
113060 DEBUG [RMI TCP Connection(1)-10.1.21.36] impl.SessionImpl - loading [com.tab.core.shared.vo.MC_AchHeader#com.tab.core.shared.vo.MC_AchHeaderPK {achHeader='1011243846576910001340312090342Z'}]
113060 DEBUG [RMI TCP Connection(1)-10.1.21.36] impl.SessionImpl - attempting to resolve [com.tab.core.shared.vo.MC_AchHeader#com.tab.core.shared.vo.MC_AchHeaderPK {achHeader='1011243846576910001340312090342Z'}]
113060 DEBUG [RMI TCP Connection(1)-10.1.21.36] impl.SessionImpl - resolved object in session cache [com.tab.core.shared.vo.MC_AchHeader#com.tab.core.shared.vo.MC_AchHeaderPK {achHeader='1011243846576910001340312090342Z'}]
113065 DEBUG [RMI TCP Connection(1)-10.1.21.36] impl.SessionImpl - saving [com.tab.core.shared.vo.MC_IncomingAchBatch#<null>]
113066 DEBUG [RMI TCP Connection(1)-10.1.21.36] persister.EntityPersister - Inserting entity: com.tab.core.shared.vo.MC_IncomingAchBatch (native id)
113066 DEBUG [RMI TCP Connection(1)-10.1.21.36] impl.BatcherImpl - about to open: 0 open PreparedStatements, 0 open ResultSets
113066 DEBUG [RMI TCP Connection(1)-10.1.21.36] impl.SessionFactoryImpl - prepared statement get: insert into ach_batch (ach_header, company_data, ach_class, company_desc, ach_date, effective_date, company_id, company_name) values (?, ?, ?, ?, ?, ?, ?, ?)
113066 DEBUG [RMI TCP Connection(1)-10.1.21.36] impl.SessionFactoryImpl - preparing statement
113068 DEBUG [RMI TCP Connection(1)-10.1.21.36] persister.EntityPersister - Dehydrating entity: com.tab.core.shared.vo.MC_IncomingAchBatch#null
113068 DEBUG [RMI TCP Connection(1)-10.1.21.36]

type.StringType - binding '1011243846576910001340312090342Z' to parameter: 1
113069 DEBUG [RMI TCP Connection(1)-10.1.21.36] type.StringType - binding '' to parameter: 2
113069 DEBUG [RMI TCP Connection(1)-10.1.21.36] type.StringType - binding 'PPD' to parameter: 3
113070 DEBUG [RMI TCP Connection(1)-10.1.21.36] type.StringType - binding 'DIR DEP' to parameter: 4
113070 DEBUG [RMI TCP Connection(1)-10.1.21.36] type.StringType - binding '1521242334' to parameter: 7
113070 DEBUG [RMI TCP Connection(1)-10.1.21.36] type.StringType - binding 'HMSHOST SERVICES' to parameter: 8

113110 DEBUG [RMI TCP Connection(1)-10.1.21.36] util.JDBCExceptionReporter - SQL Exception
java.sql.SQLException: Missing key in referenced table for referential constraint (fk_ach_batch1).

--------------------------------------- End Log ---------------------------------

Here are the 2 hbm files.

<hibernate-mapping>
<!-- com.tab.core.shared.vo.MC_AchHeader root -->
<class name="com.tab.core.shared.vo.MC_AchHeader" table="mc_ach_header">
<composite-id name="key" class="com.tab.core.shared.vo.MC_AchHeaderPK">
<key-property name="achHeader" column="ach_header" type="string"/>
</composite-id>
<property name="processTime" column="process_time" type="integer"/>
<property name="processDate" column="process_date" type="com.tab.core.server.types.IntToCalendarType"/>
</class>
</hibernate-mapping>

<hibernate-mapping>
<!-- com.tab.core.shared.vo.MC_AchBatch root -->
<class name="com.tab.core.shared.vo.MC_IncomingAchBatch" table="ach_batch">
<id name="batchId" column="batch_id" type="integer">
<generator class="native"/>
</id>
<component name="achHeader" class="com.tab.core.shared.vo.MC_AchHeaderPK">
<property name="achHeader" column="ach_header" type="string"/>
</component>
<property name="companyData" column="company_data" type="string"/>
<component name="achClass" class="com.tab.core.shared.vo.MC_AchClassPK">
<property name="achClass" column="ach_class" type="string"/>
</component>
<property name="companyDesc" column="company_desc" type="string"/>
<property name="achDate" column="ach_date" type="com.tab.core.server.types.IntToCalendarType"/>
<property name="effectiveDate" column="effective_date" type="com.tab.core.server.types.IntToCalendarType"/>
<property name="companyId" column="company_id" type="string"/>
<property name="companyName" column="company_name" type="string"/>
</class>
</hibernate-mapping>

<hibernate-mapping>
<!-- com.tab.core.shared.vo.MC_AchTransaction root -->
<class name="com.tab.core.shared.vo.MC_AchTransaction" table="mc_ach_tx">
<id name="achId" column="ach_id" type="integer">
<generator class="native"/>
</id>
<property name="traceNumber" column="trace_num" type="string"/>
<property name="reviewed" column="reviewed" type="com.tab.core.server.types.CharToBooleanType"/>
<property name="amount" column="amount" type="com.tab.core.server.types.IntToDoubleType"/>
<property name="accountNumber" column="acct_num" type="string"/>
<component name="transCode" class="com.tab.core.shared.vo.TAB_TransactionCodePK">
<property name="transCode" column="trans_code" type="integer"/>
</component>
<property name="memoId" column="memo_id" type="integer"/>
<component name="batchId" class="com.tab.core.shared.vo.MC_IncomingAchBatchPK">
<property name="batchId" column="batch_id" type="integer"/>
</component>
<property name="idNumber" column="id_number" type="string"/>
<property name="rejected" column="rejected" type="com.tab.core.server.types.CharToBooleanType"/>
<property name="correctedAccountNumber" column="corrected_acct_num" type="string"/>
<property name="accountHolder" column="acct_holder" type="string"/>
</class>
</hibernate-mapping>

<hibernate-mapping>
<!-- com.tab.core.shared.vo.MC_AchAddendem root -->
<class name="com.tab.core.shared.vo.MC_AchAddendem" table="ach_addendem">
<id name="id" column="addendem_id" type="integer">
<generator class="native"/>
</id>

<property name="sequenceNumber" column="sequence_num" type="integer"/>
<component name="returnCode" class="com.tab.core.shared.vo.MC_AchReturnCodePK">
<property name="returnCode" column="return_code" type="string"/>
</component>
<component name="achTransaction" class="com.tab.core.shared.vo.MC_AchTransactionPK">
<property name="achId" column="ach_id" type="integer"/>
</component>
<property name="data" column="data" type="string"/>
</class>
</hibernate-mapping>


I hope this will help to explain my situation a bit better.

Nic


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 10, 2003 6:46 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Read the FAQ please.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 10, 2003 6:47 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
http://www.hibernate.org/117.html#A8


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 10, 2003 6:49 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
I think that what you actually want is a many-to-one mapping instead of your component referencing PKs. Have a look at the reference doc on that subject.

_________________
Emmanuel


Top
 Profile  
 
 Post subject: Regarding the FAQ
PostPosted: Thu Dec 11, 2003 1:36 pm 
Beginner
Beginner

Joined: Tue Sep 02, 2003 12:15 pm
Posts: 33
I read through the faq and it says I would need to flush the Header object before the other objects with foreign key references to this one could see it. This is because it uses a different id generation strategy. I'm trying to do all of this inside 1 transaction. If I flush it, doesn't it end the session/transaction? Also, I can't roll back if one of the other inserts fails.

get Session
begin Transaction
save header record
save batch records (w/ foreign key constraint on a header record)
save transaction records (w/foreign key constraint on a batch record)
save addendem records (w/foreign key constraint on a transaction record)
commit Transaction

This is how I'm currently doing it. It just doesn't make sense that I should have to flush after the header record is saved and not after any of the others. They all have the same type of constraint on eachother. The only one that doesn't work in this scenario is when the first batch record is saved. Thats where I get the error. However, if I use another session and flush the header before I begin the transaction, I get no errors. Everything else saves fine. I'm sure its got to be something simple or something I've overlooked.

As far as the 1 .. many mapping, I just have so much data to deal with that returning full compound objects wasn't possible in many instances. Even with lazy loading, the client is generally on another network and the session has been long closed by the time they get the data. Thats why I am using keys.


Top
 Profile  
 
 Post subject: Re: Regarding the FAQ
PostPosted: Fri Dec 12, 2003 6:48 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
nholbrook wrote:
If I flush it, doesn't it end the session/transaction?

No link. It just ask the DB to do some work inside the transaction. Actually the same stuff you do when you use JDBC. Hibernate just cache SQL statement to optimize them.

nholbrook wrote:
It just doesn't make sense that I should have to flush after the header record is saved and not after any of the others. They all have the same type of constraint on eachother.

Why don't you just give it a try

_________________
Emmanuel


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.