0

Hibernate V.4.1.8 最終版

春: 3.1.3 リリース

シナリオ:顧客登録プロセス中に、ユーザーは完全に入力します。彼は、フォームを確定する前にフォームを複数回保存することが許可されており、送信をクリックして内容を確定します。アプリケーションは、最終送信後にのみ顧客 ID を作成します。この機能を実現するために、同じ POJO に基づいて 2 つのテーブルを作成しています。参照: 同じ POJO を複数のテーブルにマッピングする

問題: Customer テーブルにデータを保存するとき。hibernate はレコードを Address テーブルに挿入し、直接 family テーブルに挿入しますが、customer テーブルは無視します。したがって、例外をスローします: 子行を追加または更新できません: 外部キー制約が失敗します

custDetail オブジェクトがバックアップ テーブルと顧客テーブルにある間は、SQL シーケンスを参照してください。

バックアップ テーブルへの挿入

Hibernate: insert into mypack.address_bk (address1, address2, city, emailAddress, faxNo, landLineNo, mobileNo, pincode, state, verified) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into mypack.address_bk (address1, address2, city, emailAddress, faxNo, landLineNo, mobileNo, pincode, state, verified) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into mypack.address_bk (address1, address2, city, emailAddress, faxNo, landLineNo, mobileNo, pincode, state, verified) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into mypack.customer_bk (version, custId, custBirthDate, custEducation, custFirstName, custGender, custLastName, custMiddleName, custTitle, exServiceManFlag, fatherFullName, handicappedFlag, motherFullName, staffFlag, status, userId, bankCode, branchCode, customerPhoto, currentAddress, permanentAddress, officeAddress) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into mypack.family_bk (custId, memberName, relation, birthDate, gender, occupation) values (?, ?, ?, ?, ?, ?)

顧客テーブルへの挿入

Hibernate: insert into mypack.address (address1, address2, city, emailAddress, faxNo, landLineNo, mobileNo, pincode, state, verified) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into mypack.address (address1, address2, city, emailAddress, faxNo, landLineNo, mobileNo, pincode, state, verified) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into mypack.address (address1, address2, city, emailAddress, faxNo, landLineNo, mobileNo, pincode, state, verified) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into mypack.family (custId, memberName, relation, birthDate, gender, occupation) values (?, ?, ?, ?, ?, ?)
SQL Error: 1452, SQLState: 23000 Cannot add or update a child row: a foreign key constraint fails

テーブル定義:

<class entity-name="com.boss.mypack.model.Customer" lazy="true"
    name="com.boss.mypack.model.Customer" polymorphism="explicit"
    schema="mypack" table="customer">
    <id length="15" name="custId" type="string">
        <column length="20" name="custId" />
        <generator class="assigned" />
    </id>
    <version column="version" generated="never" name="version"
        type="integer" unsaved-value="null" />
    <property generated="never" lazy="false" name="tempId" type="java.lang.Integer"> 
        <column name="tempId" not-null="false" /> 
    </property>
    <many-to-one cascade="all" class="com.boss.mypack.model.Address"
        entity-name="com.boss.mypack.model.Address" fetch="select" lazy="false"
        name="OfficeAddress">
        <column name="officeAddress" />
    </many-to-one>
    <set cascade="all" fetch="select" inverse="true" lazy="true" name="family"
        sort="unsorted" table="family">
        <key>
            <column length="20" name="custId" />
        </key>
        <one-to-many class="com.boss.mypack.model.Family"
            entity-name="com.boss.mypack.model.Family" />
    </set>
</class>

バックテーブル:

<class entity-name="bkCustomer" lazy="true"
    name="com.boss.mypack.model.Customer" polymorphism="explicit"
    schema="mypack" table="customer_bk">
    <id length="4" name="tempId" type="java.lang.Integer">
        <column length="20" name="tempId" />
        <generator class="identity" />
    </id>
    <version column="version" generated="never" name="version"
        type="integer" unsaved-value="null" />
    <property generated="never" lazy="false" name="custId" type="string">
        <column length="20" name="custId" />
    </property>
    <many-to-one cascade="all" class="com.boss.mypack.model.Address"
        entity-name="bkAddress" fetch="select" lazy="false" name="OfficeAddress">
        <column name="officeAddress" />
    </many-to-one>
    <set cascade="all" fetch="select" inverse="true" lazy="true" name="family"
        sort="unsorted" table="bkfamily">
        <key>
            <column length="20" name="custId" />
        </key>
        <one-to-many class="com.boss.mypack.model.Family"
            entity-name="bkFamily" />
    </set>
</class>

保存方法:

public void saveCustomer(Customer custDetails) {
    Session session;
    session = getSessionFactory().getCurrentSession();  
    session.beginTransaction();

    try {
        session.saveOrUpdate("bkCustomer", custDetails);
        session.getTransaction().commit();
    } catch (Exception e) {
        session.getTransaction().rollback();
        e.printStackTrace();
    }
}

顧客メソッドの承認

@Override
public void approveCustomer(Customer custDetails) {
    Session session = null;
    // Saving Customer details to Database
    try {
        //TODO:Need to this in single session, In failure, every changes should get rolled back.
        //Removing from backup Table
        session = getSessionFactory().getCurrentSession();  
        session.beginTransaction();
        session.delete("bkCustomer", custDetails);
        session.getTransaction().commit();
        System.out.println("**** Record Deleted ****");

        session = getSessionFactory().getCurrentSession();  
        session.beginTransaction();

        // check to see whether this is new customer.
        if (custDetails.getCustId() == null) {
            // New Customer - Generate Customer ID
            custDetails.setTempId(null);
            custDetails.setCustId(getNextCustomerCode(session));

            // Clear all Auto Generated IDs
            custDetails.getCurrentAddress().setAddressId(null);
            custDetails.getOfficeAddress().setAddressId(null);
            custDetails.getPermanentAddress().setAddressId(null);
            // custDetails.getPhotoMaster().setPhotoId(0);

            Set<Family> familyMembers = custDetails.getFamily();

            for (Family member : familyMembers) {
                member.setMemberId(null);
            }
        } else {
            System.out.println("**** This customer is already present in Database");
        }

        custDetails.setStatus("A");

        session.saveOrUpdate("com.boss.mypack.model.Customer", custDetails);

        //Following works properly, updates Backup tables
        //session.saveOrUpdate("bkCustomer", custDetails);

        session.getTransaction().commit();

        // Saving Customer details to LDAP.
        // ldapDAO.saveOrUpdate(custDetails);
        // session.getTransaction().commit();
    } catch (Exception e) {
        session.getTransaction().rollback();
        e.printStackTrace();
    }
}

顧客テーブルで例外が発生していません。DOZER を使用して、session.clear/flash/evict/merge/replicate などを使用してオブジェクトをデタッチしようとしましたが、進行しません。私もカスケードオプションを削除しようとしました。

どこが間違っているのかわかりません。助けてください。

よろしく、

シリッシュ

4

1 に答える 1

0

あなたの制約はすぐにありますか?それらを延期します。そうすれば、hibernateは、トランザクションが終了する前に制約違反を取得することなく、すべてのテーブルを書き込むことができます。

MySQLを使用している場合、トランザクションの最後まで制約を延期することはできません。次に、常に一貫性のある状態をデータベースに挿入していることを確認する必要があります。つまり、コードの一部を書き直して、2つの保存を効果的に発行することを意味します。1つは顧客のみを保存し、もう1つは顧客を家族属性で保存します。

とにかく、Hibernateが最初にファミリを挿入しようとした理由を見つけるのは興味深いことですが、bkテーブルでは挿入の順序は予想どおりです。推測:ステートメントを移動してみてください

 custDetails.setStatus("A");

ifブロックの上

// check to see whether this is new customer.
    if (custDetails.getCustId() == null) {
        // New Customer - Generate Customer ID
        custDetails.setTempId(null);
        custDetails.setCustId(getNextCustomerCode(session));

        // Clear all Auto Generated IDs
        custDetails.getCurrentAddress().setAddressId(null);
        custDetails.getOfficeAddress().setAddressId(null);
        custDetails.getPer...

そうすれば、ファミリが最後に編集されたエンティティであり、コードが機能するため、Hibernateは挿入を並べ替えることができます。とにかく、それはHibernateの内部に大きく依存します。前に説明したように、2つの保存を使用することをお勧めします。

于 2012-12-15T20:31:14.080 に答える