【发布时间】:2013-10-26 22:25:09
【问题描述】:
我面临的问题是,我的 DAO 尝试再次保存现有对象,而不是更新。 (它会创建一个新的)
这发生在 hibernateTemplate 的 saveOrUpdate- 和 merge- 方法中。传递的对象始终包含一个 ID(PK、自动递增、标识生成器类),因此它应该更新。
抛出异常:
2013-10-18 08:31:19,660 [WARN ] [JDBCExceptionReporter.java : 77] org.hibernate.util.JDBCExceptionReporter - SQL Error: 1062, SQLState: 23000
2013-10-18 08:31:19,664 [ERROR] [JDBCExceptionReporter.java : 78] org.hibernate.util.JDBCExceptionReporter - Duplicate entry '2012-10-17-241' for key 'YEAR_PRODUCER_ID_BRAND_ID_MODEL_ID'
2013-10-18 08:31:19,666 [ERROR] [AbstractFlushingEventListener.java : 301] org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
异常是在休眠类中的某个地方引发的,因为我无法在调试模式下使用 try-catch 子句捕获它们。
我的问题是,这种情况并非每次都会发生。只有四五次。我怀疑我有会话问题,但我不知道真正出了什么问题。
我的会话 FLUSH_MODE 设置为 AUTO
谢谢,如果您需要更多信息,请告诉我
更新 1:实体 hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com..model.Bonus" table="bonus" catalog="cartool">
<id name="id" type="integer">
<column name="ID" />
<generator class="identity" />
</id>
<many-to-one name="brand" class="com..model.Brand" fetch="select">
<column name="BRAND_ID" />
</many-to-one>
<many-to-one name="model" class="com..model.Model" fetch="select">
<column name="MODEL_ID" />
</many-to-one>
<many-to-one name="producer" class="com..model.Producer" fetch="select">
<column name="PRODUCER_ID" />
</many-to-one>
<property name="year" type="integer">
<column name="YEAR" />
</property>
<property name="low" type="integer">
<column name="LOW" not-null="true" />
</property>
<property name="high" type="integer">
<column name="HIGH" not-null="true" />
</property>
<property name="bonusValue" type="double">
<column name="BONUS_VALUE" />
</property>
<property name="otherTextProducer" type="string">
<column name="OTHER_TEXT_PRODUCER" length="50" />
</property>
<property name="otherTextBrand" type="string">
<column name="OTHER_TEXT_BRAND" length="50" />
</property>
<property name="deleted" type="integer">
<column name="DELETED" />
</property>
</class>
</hibernate-mapping>
更新 2:休眠日志记录
2013-10-18 11:18:20,637 [DEBUG] [AbstractBatcher.java : 424] org.hibernate.SQL - update cartool.bonus set BRAND_ID=?, MODEL_ID=?, PRODUCER_ID=?, YEAR=?, LOW=?, HIGH=?, BONUS_VALUE=?, OTHER_TEXT_PRODUCER=?, OTHER_TEXT_BRAND=?, DELETED=? where ID=?
2013-10-18 11:18:20,637 [DEBUG] [NullableType.java : 133] org.hibernate.type.IntegerType - binding '17' to parameter: 1
2013-10-18 11:18:20,637 [DEBUG] [NullableType.java : 133] org.hibernate.type.IntegerType - binding '252' to parameter: 2
2013-10-18 11:18:20,637 [DEBUG] [NullableType.java : 133] org.hibernate.type.IntegerType - binding '10' to parameter: 3
2013-10-18 11:18:20,637 [DEBUG] [NullableType.java : 133] org.hibernate.type.IntegerType - binding '2012' to parameter: 4
2013-10-18 11:18:20,637 [DEBUG] [NullableType.java : 133] org.hibernate.type.IntegerType - binding '400' to parameter: 5
2013-10-18 11:18:20,637 [DEBUG] [NullableType.java : 133] org.hibernate.type.IntegerType - binding '549' to parameter: 6
2013-10-18 11:18:20,637 [DEBUG] [NullableType.java : 133] org.hibernate.type.DoubleType - binding '100.0' to parameter: 7
2013-10-18 11:18:20,637 [DEBUG] [NullableType.java : 133] org.hibernate.type.StringType - binding '' to parameter: 8
2013-10-18 11:18:20,637 [DEBUG] [NullableType.java : 133] org.hibernate.type.StringType - binding '' to parameter: 9
2013-10-18 11:18:20,637 [DEBUG] [NullableType.java : 133] org.hibernate.type.IntegerType - binding '0' to parameter: 10
2013-10-18 11:18:20,637 [DEBUG] [NullableType.java : 133] org.hibernate.type.IntegerType - binding '896' to parameter: 11
这个输出出现在异常之前
【问题讨论】:
-
YEAR_PRODUCER_ID_BRAND_ID_MODEL_ID听起来确实像复合键。我们能看到实体吗? -
是的,你是对的,它是复合唯一键。但我认为这不是问题。该键触发是因为 hibernate 尝试插入一个已经存在的条目。如果休眠将更新而不是创建新条目,则密钥将永远不会触发。
-
我发现了一些类似的问题:programmingforfuture.com/2013/05/…stackoverflow.com/questions/1105734/…你确定,物理模式是你想要定义的吗?
-
这很奇怪。我启用了休眠日志,如您所见,休眠进行了更新。并且所有参数都是正确的,但仍然会触发唯一约束。
-
我们能看到唯一索引定义吗?
标签: java hibernate session merge autoflush