2009-05-26 16 views
0

Wenn ich versuche, das Objekt RFQ zu aktualisieren, neigt Hibernate dazu, seine Kind Sammlung BQMaster zu aktualisieren und versuchen, die Kennung von BQMaster setzen und aktualisieren, die normalerweise nicht erlaubt sein sollte.Hibernate - Kind Sammlung Identifier in Update geändert

Die postgre Protokolldatei:
2009-05-22 11:16:53 ERROR: doppelte Schlüssel verletzt eindeutige Einschränkung "bq_masters_pkey"
2009-05-22 11:16:53 STATEMENT: Update bq_masters gesetzt rfq_id = $ 1, $ id = 2 wo id = 3 $

Fehler in der Konsole:
Verursacht von: java.sql.BatchUpdateException: Batch-Eintrag 0 Update bq_masters Satz rf q_id = 2, ID = 0 wobei id = 49449 wurde abgebrochen. Rufen Sie getNextException auf, um die Ursache zu sehen .
bei org.postgresql.jdbc2.AbstractJdbc2Statement $ BatchResultHandler.handle Error (AbstractJdbc2Statement.java:2392)
bei org.postgresql.core.v3.QueryExecutorImpl.processResults (QueryExecutor Impl.java:1257)
bei org.postgresql.core.v3.QueryExecutorImpl.execute (QueryExecutorImpl.ja va: 334)
bei org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch (AbstractJdbc 2Statement.java:2451)
bei org.hibernate.jdbc.BatchingBatcher.doExecuteBatch (BatchingBatcher.jav a: 58)
bei org.hibernate.jdbc.AbstractBatcher.executeBatch (AbstractBatcher.java: 195)
. .. 32 mehr

Es scheint sehr seltsam, wie es versucht, die ID von bq_masters zu aktualisieren. Es sollte die ID beibehalten und nur die anderen Felder aktualisieren.

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 Mapping:

<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> 

Datenbankstrukturen als Referenz:

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 
); 

ich versucht habe inverse Zugabe = "true" in RFQ one-to-many-Mapping, aber ohne Erfolg , da die BQMaster des entsprechenden RFQ-Objekts nicht aktualisiert werden.

Hat jemand eine Ahnung davon, dieses Problem zu lösen? Danke im Voraus.

Antwort

0

Hibernate macht genau das, was Sie im Speicher tun. Sie setzen die bqmasters in die bqMasters-Tabelle, und Sie haben diese Relation der Spalte rfq_id in bqmasters zugeordnet, sodass der Fremdschlüssel aktualisiert wird.

Sie müssen inverse dafür verwenden. Dieselbe Spalte rfq_id wird für zwei Eigenschaften verwendet, nur eine könnte von Hibernate verwendet werden.

Sie haben tatsächlich ein Konsistenzproblem im Speicher. Wenn Sie der Liste einen bqmaster hinzufügen, müssen Sie auch die Eigenschaft rfq aktualisieren, da sie die gleiche Parent-Child-Beziehung enthält und auch derselben Datenbankspalte zugeordnet ist.

Übrigens müssen Sie Update für Objekte, die bereits in der Sitzung sind, nicht aufrufen. Hibernate meldet, dass sich das Objekt geändert hat und aktualisiert es.

Verwandte Themen