Hibernate-在更新中更改了子集合标识符

Hibernate-在更新中更改了子集合标识符,hibernate,one-to-many,many-to-one,Hibernate,One To Many,Many To One,当我尝试更新对象RFQ时,Hibernate倾向于更新其子集合BQMaster,并尝试设置和更新BQMaster的标识符,这通常是不允许的 postgre日志文件: 2009-05-22 11:16:53错误:重复密钥违反唯一约束“bq_masters_pkey” 2009-05-22 11:16:53声明:更新bq_主控设置rfq_id=$1,id=$2其中id=$3 控制台中出现错误: 原因:java.sql.BatchUpdateException:批处理条目0更新bq\U主设置rf q_

当我尝试更新对象RFQ时,Hibernate倾向于更新其子集合BQMaster,并尝试设置和更新BQMaster的标识符,这通常是不允许的

postgre日志文件:
2009-05-22 11:16:53错误:重复密钥违反唯一约束“bq_masters_pkey”
2009-05-22 11:16:53声明:更新bq_主控设置rfq_id=$1,id=$2其中id=$3

控制台中出现错误:
原因:java.sql.BatchUpdateException:批处理条目0更新bq\U主设置rf q_id=2,id=0,其中id=49449被中止。调用getNextException查看原因 .
位于org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handle 错误(AbstractJdbc2Statement.java:2392)
位于org.postgresql.core.v3.QueryExecutorImpl.processResults(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 a:58)
在org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java: 195)
... 32多

这看起来很奇怪,因为它试图更新bq_大师的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);  
休眠映射:

<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>
我曾尝试在RFQ一对多映射中添加inverse=“true”,但没有效果,因为它不会更新相应RFQ对象的BQMasters


有人有解决这个问题的线索吗?提前感谢。

Hibernate做的正是你在内存中所做的。您正在将bqmasters放入bqmasters表中,并将此关系映射到bqmasters中的
rfq\u id
列,因此它会更新外键

对此,必须使用反向。同一列
rfq\u id
用于两个属性,Hibernate只能使用其中一个属性

实际上,内存中存在一致性问题。如果将bqmaster添加到列表中,还需要更新它的rfq属性,因为它具有相同的父子关系,并且映射到相同的数据库列

顺便说一下,您不必对会话中已经存在的对象调用update。Hibernate将通知对象已更改,并将对其进行更新

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