我有一个Hibernate模型,它使用自定义类型来表示布尔字段(即模型有一个'Boolean'对象,但数据库将0或1写入TINYINT字段。更改布尔对象的值from(true to false或false to true)将更改对象的值,但Hibernate会话管理器似乎认为对象没有任何值更改,因此save()
实际上不会将SQL写入DB。
我是否需要在自定义类型中执行一些特殊操作才能让它看到更改?我宁愿强迫每个对象在访问器中“脏”,但这也是可能的。
答案 0 :(得分:2)
有两种解决方案。
Hibernate调用equals方法来检查对象是否已被更改,在此之前它调用deepCopy方法来获取自定义对象的副本。因此,在您的deepCopy方法中,创建自定义对象的新副本并正确实现equals方法。
第二种解决方案是使用混合方法AccessType.FIELD和AccessType.PROPERTY。虽然不建议这样做,但你可以看看它是否能让你知晓。
这似乎与您的映射类似,如下所示。
@Entity @Table(name = TABLE_NAME)
<强> @Access(AccessType.FIELD)强>
public class EntityClass {
/// ---某些字段
@Column(name =“CustomCol”)
@Type(type =“com.something.CustomColType”)
CustomClass customClass;
// - getters settters
}
如果在ur类中有自定义对象,并且只修改了该对象,则它不会标记为脏对象。 解决方案1:使用customClass对象更新其他一些属性。 解决方案2:在customClass字段上输入 @Access(AccessType.PROPERTY),并为其提供getter / setter。 这将覆盖您在类级别上放置的默认AccessType.Field行为。
如果您在课程级别上 @Access(AccessType.PROPERTY),则此问题将无法重现。
答案 1 :(得分:1)
首先,您是否有任何理由使用自定义类型而不是Hibernate的内置布尔类型?
<property name="some_flag" type="boolean"/>
其次,不,您不需要在自定义类型中执行任何“特殊”操作,但您需要正确实施其equals()
和deepCopy()
方法。你可以发布消息来源吗?
答案 2 :(得分:0)
save()
实际上并没有将对象(或它的更改)保存到数据库中。它将它标记为持久性,即Hibernate认为管理的对象。如果对象已分离,请致电update()
。
你的工作完成后是flushing the Session吗?和/或closing it?
您可能需要仔细检查Modifying Persistent Objects上的Hibernate手册(我不是说这是狡猾的;我今天遇到了与Hibernate相同的问题 - 忘记了save()
和flush()
之间的区别其他方法,也忘了{{1}}我的会话。