2009-05-26 11 views
0

に変更、Hibernateはその子コレクションBQMasterを更新する傾向があり、通常はそれが許されるべきではないBQMasterの識別子を設定し、更新しようとします。 Hibernateは - 私は、オブジェクトのRFQを更新しようとしたとき、子コレクション識別子が更新

postgreログファイル:
2009-05-22 11時16分53秒ERROR:重複キーが
2009-05-22 11時16分53秒STATEMENT "bq_masters_pkey" ユニーク制約に違反:
:更新がコンソールにrfq_id = $ 1、ID = $ 2ID = $ 3

誤差を設定bq_masters java.sql.BatchUpdateException:によって引き起こさバッチエントリ0 更新bq_mastersは、RF q_id = 2、ID = 49449が中止されたID = 0を設定します。 getNextExceptionを呼び出して原因を確認してください 。 org.postgresql.core.v3.QueryExecutorImpl.processResultsで org.postgresql.jdbc2.AbstractJdbc2Statement $ BatchResultHandler.handle エラー(AbstractJdbc2Statement.java:2392)

(QueryExecutor Impl.java:1257) org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.ja VA:334)で
org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc 2Statement.java:2451)で
org.hibernate.jdbc.BatchingBatcher.doExecuteBatchで
(BatchingBatcher.jav :58)org.hibernate.jdbc.AbstractBatcher.executeBatchで
(AbstractBatcher.java: 195)
。 ...もっと32

bq_mastersのIDを更新しようとしたとして、非常に奇妙なようです。 idを保持し、他のフィールドだけを更新する必要があります。

Criteria crit = session.createCriteria(BQMaster.class); 
crit.add(Restrictions.eq("project",project); 
crit.setFirstResult(5); 
crit.setMaxResult(2); 
List bqMasters = crit.list(); 

RFQ rfq = (RFQ)session.get(RFQ.class, RFQId); 
rfq.setBqMasters(bqMasters); 
session.update(rfq); 

Hibernateマッピング:参照用

<class name="RFQ" table="rfq"> 
    <id name="id" column="id"> 
    <generator class="native"> 
     <param name="sequence">rfq_id_seq</param> 
    </generator> 
    </id> 

    <property name="reference" column="reference" /> 
    <property name="status" column="status" /> 
    <property name="created" column="created" /> 
    <property name="modified" column="modified" /> 

    <many-to-one name="project" class="Project" column="project_id" cascade="save-update" /> 

    <list name="subcons" table="rfq_subcons"> 
    <key column="rfq_id" /> 
    <list-index column="id"/> 
    <many-to-many class="Subcon" column="subcon_id"/> 
    </list> 

    <list name="bqMasters"> 
    <key column="rfq_id" /> 
    <list-index column="id"/> 
    <one-to-many class="BQMaster"/> 
    </list> 
</class> 

<class name="BQMaster" table="bq_masters"> 
    <id name="id" column="id"> 
    <generator class="native"> 
     <param name="sequence">bq_masters_id_seq</param> 
    </generator> 
    </id> 

    <property name="reference" column="reference" /> 
    <property name="description" column="description" /> 
    <property name="lod" column="lod" /> 
    <property name="uom" column="uom" /> 
    <property name="quantity" column="quantity" /> 
    <property name="parentId" column="parent_id" /> 
    <property name="groupId" column="group_id" /> 
    <property name="leaf" column="leaf" /> 
    <property name="active" column="active" /> 
    <property name="subcontract" column="subcontract" /> 
    <property name="created" column="created" /> 
    <property name="modified" column="modified" /> 

    <many-to-one name="project" class="Project" column="project_id" cascade="save-update" /> 

    <many-to-one name="page" class="Page" column="page_id" cascade="save-update" /> 

    <many-to-one name="rfq" class="RFQ" column="rfq_id" cascade="save-update" /> 

</class> 

データベース構造:

CREATE TABLE rfq 
( 
    id bigserial NOT NULL, 
    project_id bigint, 
    reference text, 
    status text, 
    created timestamp without time zone, 
    modified timestamp without time zone, 
    CONSTRAINT rfq_pkey PRIMARY KEY (id), 
    CONSTRAINT rfq_project_id_fkey FOREIGN KEY (project_id) 
    REFERENCES projects (id) MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE 
); 

CREATE TABLE bq_masters 
(
    id bigserial NOT NULL, 
    reference varchar(100), 
    project_id bigint, 
    page_id bigint, 
    rfq_id bigint, 
    description text, 
    lod integer, 
    uom varchar(20), 
    quantity numeric, 
    parent_id bigint, 
    group_id bigint, 
    leaf boolean, 
    active boolean, 
    subcontract boolean, 
    created timestamp without time zone, 
    modified timestamp without time zone, 
    CONSTRAINT bq_masters_pkey PRIMARY KEY (id), 
    CONSTRAINT bq_masters_project_id_fkey FOREIGN KEY (project_id) 
    REFERENCES projects (id) MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE, 
    CONSTRAINT bq_masters_page_id_fkey FOREIGN KEY (page_id) 
    REFERENCES pages (id) MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE, 
    CONSTRAINT bq_masters_rfq_id_fkey FOREIGN KEY (rfq_id) 
    REFERENCES rfq (id) MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE 
); 

私は対多の1のマッピングが、無駄にRFQに逆= "true" を追加しようとしています対応するRFQオブジェクトのBQMasterを更新しないためです。

は、誰もがこの問題を解決する上の任意の手掛かりを持っていますか?前もって感謝します。

答えて

0

メモリ内で行っていることをHibernateが正確に行います。 bqmastersをbqMastersテーブルに入れ、この関係をbqmastersのrfq_idカラムにマップして、外部キーを更新します。

これにはinverseを使用する必要があります。同じカラムrfq_idは2つのプロパティに使用され、1つしかHibernateで使用できません。

実際にはメモリに一貫性の問題があります。リストにbqmasterを追加する場合、同じ親子関係を保持しているため同じrfcプロパティを更新する必要があります。同じ親子関係も同じデータベース列にマッピングされています。

ところで、すでにセッションにあるオブジェクトの更新を呼び出す必要はありません。 Hibernateは、オブジェクトが変更されたことを通知し、オブジェクトを更新します。

関連する問題