我在重复使用记录来填充交叉引用表时遇到问题。 Hibernate尝试更新外键记录而不是填充交叉引用表。
插入新记录可以正常工作。
DB Diagram
当我添加新位置并将它们链接到交叉引用表中时,它可以正常运行:
//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
映射
TestContainer.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>
TestContainerLocation.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>
答案 0 :(得分:0)
使用session.get()
或load()
代替new TestContainerLocation()
。例如:
TestContainerLocation loc1 = (TestContainerLocation) session.load(TestContainerLocation.class, 1);
编辑:当您使用TestContainerLocation
然后设置ID时,Hibernate会尝试更新new()
实体。
答案 1 :(得分:0)
此错误由您的默认字符串大小字符
组成 你有两个选择来解决这个问题 1.你必须要字符串大小
示例
<property name="companyname" column="company_name" length='25' />
您的公司名称大小必须小于25 2.将类型更改为文本 示例
<property name="companyname" column="company_name" type='text' />