我在重用记录来填充交叉引用表时遇到问题。Hibernate 尝试更新外键记录而不是填充交叉引用表。
插入新记录工作正常。
数据库图
当我添加新位置并将它们链接到交叉引用表中时,它可以正常工作:
//Get specific object
TestContainer tc = (TestContainer) session.createQuery("from TestContainer where id = :id")
.setParameter("id", id).list().get(0);
//Locations
Set<TestContainerLocation> tcl = new HashSet<TestContainerLocation>();
TestContainerLocation loc1 = new TestContainerLocation();
loc1.setLocationName("String1");
TestContainerLocation loc2 = new TestContainerLocation();
loc2.setLocationName("String2");
tcl.add(loc1);
tcl.add(loc2);
tc.setTestContainerLocation(tcl);
session.saveOrUpdate(tc);
当我尝试重用现有位置时,它不会通过。它不是插入交叉引用表,而是尝试通过提供空值来更新外键表,但由于约束而失败。
//Get specific object
TestContainer tc = (TestContainer) session.createQuery("from TestContainer where id = :id")
.setParameter("id", id).list().get(0);
Set<TestContainerLocation> tcl = new HashSet<TestContainerLocation>();
TestContainerLocation loc1 = new TestContainerLocation();
loc1.setLocationId(1);//existing Id
TestContainerLocation loc2 = new TestContainerLocation();
loc2.setLocationId(2);//existing Id
tcl.add(loc1);
tcl.add(loc2);
tc.setTestContainerLocation(tcl);
session.saveOrUpdate(tc);
错误:
Hibernate: select testcontai0_.id as id0_, testcontai0_.step_one as step2_0_, testcontai0_.step_two as step3_0_, testcontai0_.step_three as step4_0_, testcontai0_.type_id as type5_0_ from test_container testcontai0_ where testcontai0_.id=?
Hibernate: update test_container_location set location_name=? where location_id=?
Hibernate: update test_container_location set location_name=? where location_id=?
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
...
Caused by: java.sql.BatchUpdateException: Column 'location_name' cannot be null
映射
测试容器.hbm.xml
<class name="TestContainer"
table="test_container">
<id name="id" column="id" type="long" unsaved-value="null">
<generator class="identity"></generator>
</id>
<property name="stepOne" type="string" length="255" column="step_one" not-null="false" />
<property name="stepTwo" type="integer" column="step_two" not-null="false" />
<property name="stepThree" type="string" length="255" column="step_three" not-null="false" />
<many-to-one name="testContainerType" class="org.test.data.TestContainerType" fetch="select">
<column name="type_id" not-null="true"/>
</many-to-one>
<set name="testContainerLocation" table="test_container_location_lookup"
inverse="false" lazy="true" fetch="select" cascade="all">
<key>
<column name="id" not-null="true"/>
</key>
<many-to-many entity-name="org.test.data.TestContainerLocation">
<column name="location_id" not-null="true" />
</many-to-many>
</set>
</class>
测试容器位置.hbm.xml
<class name="TestContainerLocation"
table="test_container_location">
<id name="locationId" column="location_id" type="integer" unsaved-value="null">
<generator class="identity"></generator>
</id>
<property name="locationName" type="string" length="255" column="location_name" not-null="false" />
<set name="testContainer" table="test_container_location_lookup"
inverse="true" lazy="true" fetch="select" cascade="all">
<key>
<column name="location_id" not-null="true"/>
</key>
<many-to-many entity-name="org.test.data.TestContainer">
<column name="id" not-null="true" />
</many-to-many>
</set>
</class>