Я надеюсь, что кто-то сталкивался с этой проблемой раньше и может мне помочь.По сути, Hibernate вставляет родительскую строку (с идентификатором, указывающим на дочернюю строку), но не вставляет эту дочернюю строку с соответствующим идентификатором, что оставляет базу данных в плохом состоянии.Вот пример исключения, которое выдается, когда Hibernate пытается загрузить неправильно сохраненный объект:
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]
Эта часть приложения имеет три объекта:
- Query , который является родительским для DataProviderTransactionReference и DataProviderTransaction
- DataProviderTransaction , который является дочерним по отношению к DataProviderTransactionReference
- DataProviderTransactionReference ,который имеет внешние ключи, указывающие на DataProviderTransaction и Query
Вот сопоставления:
От Запрос :
@OneToMany(mappedBy = "query", cascade =
{ CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY)
@Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
@JoinColumn(name = "query_id")
public List<DataProviderTransactionReference> getDataProviderTransactionReferences()
От DataProviderTransaction :
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "query_id")
public Query getQuery()
From DataProviderTransactionReference :
@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;
}
Схема выглядит следующим образом (исключая таблицу запросов, поскольку она не имеет внешних ключей):
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 | |
+------------------------------+------------+------+-----+---------+----------------+
Поэтому, как только мы закончим выполнение запроса (представленного объектом Query), мы сохраняем его, используя Spring и Hibernate, используяследующее:
getHibernateTemplate().saveOrUpdate(aQuery);
Запрос сохраняется вместе со связанными сущностями DataProviderTransaction и DataProviderTransactionReference.За исключением того, что иногда он сохраняет Query и DataProviderTransactionReference без связанной DataProviderTransaction.Он помещает идентификатор в data_provider_transaction_id, но указывает на строку, которой нет в таблице data_provider_transaction.
Следующим шагом является добавление ограничения внешнего ключа, чтобы вызвать возникновение проблемы при первоначальном выполнении.сохранить, а не когда мы попытаемся загрузить объект позже.
Мы используем Spring 2.5.6, Hibernate 3.3.2 и MySQL 5.0.Я видел, как эта проблема возникала на протяжении многих лет с более ранними версиями Spring и Hibernate.
Кто-нибудь когда-либо видел / решил эту проблему?