Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy does Hibernate insert a parent row with a foreign key without inserting the child row?
    primarykey
    data
    text
    <p>I'm hoping someone has run into this problem before and can help me out. Basically, Hibernate is inserting a parent row (with an ID pointing to a child row), but not inserting that child row with the associated ID, which leaves the database in a bad state. Here's an example of the exception that's thrown when Hibernate tries to load the improperly saved object:</p> <pre><code>27 Jun 2011 13:55:31,380 ERROR [scheduler_Worker-4] - Job DEFAULT.queryScrubJobDetail threw an unhandled Exception: org.springframework.scheduling.quartz.JobMethodInvocationFailedException: Invocation of method 'doIt' on target class [XXX] failed; nested exception is org.springframework.orm.hibernate3.HibernateObjectRetrievalFailureException: No row with the given identifier exists: [XXX.DataProviderTransaction#60739703]; nested exception is org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.idology.persist.DataProviderTransaction#2] </code></pre> <p>This part of the application has three entities:</p> <ul> <li><strong>Query</strong>, which is a parent of DataProviderTransactionReference and DataProviderTransaction</li> <li><strong>DataProviderTransaction</strong>, which is a child of Query and a parent of DataProviderTransactionReference</li> <li><strong>DataProviderTransactionReference</strong>, which has foreign keys pointing to DataProviderTransaction and Query</li> </ul> <p>Here are the mappings:</p> <p>From <strong>Query</strong>:</p> <pre><code>@OneToMany(mappedBy = "query", cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY) @Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE) @JoinColumn(name = "query_id") public List&lt;DataProviderTransactionReference&gt; getDataProviderTransactionReferences() </code></pre> <p>From <strong>DataProviderTransaction</strong>:</p> <pre><code>@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "query_id") public Query getQuery() </code></pre> <p>From <strong>DataProviderTransactionReference</strong>:</p> <pre><code>@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.EAGER) @JoinColumn(name = "data_provider_transaction_id") @Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE) public DataProviderTransaction getDataProviderTransaction() { return mDataProviderTransaction; } </code></pre> <p>The schema looks like this (leaving out the queries table since it has no foreign keys):</p> <pre><code>data_provider_transaction +------------------+---------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------------+---------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | query_id | bigint(20) | YES | MUL | NULL | | +------------------+---------------+------+-----+---------+----------------+ data_provider_txn_refs +------------------------------+------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------------------------+------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | created_at | datetime | YES | | NULL | | | data_provider_transaction_id | bigint(20) | YES | MUL | NULL | | | query_id | bigint(20) | YES | MUL | NULL | | +------------------------------+------------+------+-----+---------+----------------+ </code></pre> <p>So once we're done running a query (represented by the Query object), we save it using Spring and Hibernate using the following:</p> <pre><code>getHibernateTemplate().saveOrUpdate(aQuery); </code></pre> <p>The Query is saved along with the associated DataProviderTransaction and DataProviderTransactionReference entities. Except that sometimes it saves a Query and a DataProviderTransactionReference without the associated DataProviderTransaction. It does put an ID in the data_provider_transaction_id but it points to a row that does not exist in the data_provider_transaction table.</p> <p>The next step is to add a foreign key constraint to cause the problem to occur when we do the initial save rather than when we try to load the object later.</p> <p>We're using Spring 2.5.6, Hibernate 3.3.2, and MySQL 5.0. I've seen the problem occur over the years with earlier versions of Spring and Hibernate, though.</p> <p>Anyone ever seen/solved this problem?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload