具有自定义类型更改的Hibernate字段,但对象未标记为“脏”以进行更新

我有一个Hibernate模型,它使用自定义类型来表示布尔字段(即模型有一个’Boolean’对象,但数据库将0或1写入TINYINT字段。更改布尔对象的值(true) to false或false to true)将更改对象的值,但Hibernate会话管理器似乎并不认为对象有任何值更改,因此save()实际上不会将SQL写入DB。

我是否需要在自定义类型中执行一些特殊操作才能让它看到更改? 我宁愿强迫每个对象在访问器中“脏”,但这也是可能的。

有两种解决方案。

  1. Hibernate调用equals方法来检查对象是否已被更改,在此之前它调用deepCopy方法来获取自定义对象的副本。 因此,在您的deepCopy方法中,创建自定义对象的新副本并正确实现equals方法。

  2. 第二种解决方案是使用混合方法AccessType.FIELD和AccessType.PROPERTY。 虽然不建议这样做,但你可以看看它是否给你了解。

这似乎是您的映射应该类似如下。

@Entity @Table(name = TABLE_NAME)

@Access(AccessType.FIELD)

公共类EntityClass {

/// —一些领域

@Column(name =“CustomCol”)

@Type(type =“com.something.CustomColType”)

CustomClass customClass;

// – 吸气者安置者

}

如果在ur类中有自定义对象,并且只修改了该对象,则它不会标记为脏对象。 解决方案1:使用customClass对象更新其他一些属性。 解决方案2:在customClass字段上放置@Access(AccessType.PROPERTY)并为其提供getter / setter。 这将覆盖您在类级别上放置的默认AccessType.Field行为。

如果在类级别上有@Access(AccessType.PROPERTY) ,则此问题将无法重现。

首先,您是否有任何理由使用自定义类型而不是Hibernate的内置布尔类型?

  

其次,不,您不需要在自定义类型中执行任何“特殊”操作,但您需要正确实现其equals()deepCopy()方法。 你可以发布消息来源吗?

save()实际上并没有将对象(或它的更改)保存到数据库中。 它将它标记为持久性,即Hibernate认为管理的对象。 如果对象已分离,请调用update()

你工作完成后是否正在刷新会话 ? 和/或关闭它 ?

您可能想要仔细检查修改持久对象上的Hibernate手册(我不是说这是狡猾的;我今天遇到了与Hibernate相同的问题 – 忘记了save()和其他方法之间的区别,也忘记了flush()我的会话)。