2011-06-27 5 views
7

誰かがこの問題に遭遇して助けてくれることを願っています。基本的には、Hibernateは親行(子行を指し示すIDを持つ)を挿入していますが、関連付けられたIDを持つ子行を挿入しないため、データベースは不良状態になります。ここではHibernateは不適切に保存されたオブジェクトをロードしようとしたときにスローされます例外の例です:DataProviderTransactionReferenceの親である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] 
    

    アプリケーションのこの部分は、3つのエンティティを持っていますクエリの子とDataProviderTransactionReference

  • の親であるとDataProviderTransaction
  • DataProviderTransaction

    クエリから:

    @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 から:

    DataProviderTransactionとクエリ
  • を指している外部キーを持っている
  • DataProviderTransactionReferenceは、ここで

がマッピングされています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にIDを挿入しますが、data_provider_transactionテーブルに存在しない行を指しています。

次の手順は、外部キー制約を追加して、後でオブジェクトをロードしようとするのではなく、最初の保存を行うときに問題が発生するようにすることです。

私たちは、Spring 2.5.6、Hibernate 3.3.2、およびMySQL 5.0を使用しています。私はこの問題が以前のバージョンのSpringとHibernateで長年にわたり起こっているのを見てきました。

この問題は誰でも見たことがありますか?

+6

それはあなたの質問をundestandすることは少し難しい、あなたはしなかった関連するソースコードをエンティティ間のマッピングと結合する。しかし、私にとって間違っているのは、データベースに外部キーを持たない結合列があることです。データベースが外部キーを実施した場合、インコヒーレントなデータではなく、少なくとも例外があります。 –

+0

は、オブジェクトをデータベースに追加する方法を理解する必要があります。オブジェクトの一方または両方に 'save()'、 'update()'を呼び出すか、双方向関係の両側にデータを入れていますかあなたのクラスなどで? –

+0

プライマリキーの世代戦略は何ですか?それはアイデンティティですか?下の私の答えを見てください。 –

答えて

1

これは、MySQLでのあなたのID割り当てに問題があるようです。ジェネレータが正しく宣言されていない場合や、コードで奇妙なことをしている場合、Hibernateは混乱することがあります。

孤児のDataProviderTransactionsまたはDataProviderTransactionReferences、存在しないクエリIDを持つDataProviderTransaction、または間違ったクエリを指していますか?

あなたのジェネレータはあなたのIDのアイデンティティとして宣言されていますか? (Chapter 5. Basic O/R Mapping, section 5.1.4 idを参照してください。通常、これは十分なはずですが、休止状態混乱あなたがやっている他のものがあるかもしれません

ので、例えば:。。

@Id 
@GeneratedValue(strategy = IDENTITY) 
@Column(name = "id", unique = true, nullable = false) 

本当にこのダウンを追跡するには、あなたを必要なぜこれらの行が挿入されているのかを知るにはデータベースに外部キー制約が必要です外部キーがないため、DataProviderTransactionを削除してデータベースに不満がない可能性があります。

関連する問題