是否可以更新实体而无需在 jpa 中调用 setter
is it possible to update entity with out setters being called in jpa
我正在开发应用程序,它有一个名为 My.java 的实体,它从另一个实体扩展而来,该实体的字段名为 edited。
对于每次更新,此字段将使用当前时间戳进行更新
我正在使用单一 table 继承策略。
我正在使用 jpa/eclipse link 作为持久性提供程序。
即使没有调用 setter 方法,已编辑字段也会使用当前时间戳进行更新,我的 java 代码中没有其他引用更改此已编辑字段的值。
调试时我可以看到 UPDATE QL 语句,用于编辑字段更新。
我真的很想知道 why/how 它是值更新,是否可以不调用 setter?
这是映射的超级 class:
@MappedSuperclass
public abstract class SuperEntity implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1125783654888232605L;
/**
* The time the entry was created
*/
@Column(name = "CREATED")
private Timestamp created;
/**
* The date the entry was edited
*/
@Column(name = "EDITED")
@Version
private Timestamp edited;
是的。 JPA 实现不需要一些 属性 侦听器或代理来让您的 class 检测值已通过 setter 更新。他们如何检测托管实例的更改可能取决于实现,但支持通过直接访问而不是 getter/setter 更新字段。例如,可以保留通过持久性管理器获得的实例的副本,并且在完成事务或发出提交时,您可能已对其进行更改的托管实例将与它们的原始实例进行比较,并将对数据库的更新发布为必要的。
实际上,可以通过以下注解明确指定如何访问实体 class:https://docs.oracle.com/javaee/7/api/javax/persistence/Access.html
相反,可能有些属性不受字段支持,而是具有计算值的 getter。使用 属性 访问时,这些也会导致在从代码创建数据库时生成列,并在持久化或合并实体时生成 inserting/updating 值。
所以简而言之,仅仅调用 setter 并不能将托管实体中的 属性 或持久字段标记为 "dirty"。如果您可以直接访问一个字段并对其进行更改,那也会导致更新。
带有 @Version
注释的字段将由 hibernate 自动控制,并用于其 optimistic locking 功能。
因此,当您保存实体时,Hibernate 本身会自动设置该字段。
检查这些东西。
- 您的实体可能正在实施某种可审核接口
- 您的字段可能有@Version 注释
在第一种情况下,你已经弄清楚了接口的用法并且你可以理解它
在第二种情况下,它是 EJB 和 Hibernate 中的默认行为和预期行为。
我在谷歌搜索后得到了这个link它可能对你有用
这不是什么大事,你可以轻松克服
我正在开发应用程序,它有一个名为 My.java 的实体,它从另一个实体扩展而来,该实体的字段名为 edited。 对于每次更新,此字段将使用当前时间戳进行更新
我正在使用单一 table 继承策略。
我正在使用 jpa/eclipse link 作为持久性提供程序。
即使没有调用 setter 方法,已编辑字段也会使用当前时间戳进行更新,我的 java 代码中没有其他引用更改此已编辑字段的值。
调试时我可以看到 UPDATE QL 语句,用于编辑字段更新。
我真的很想知道 why/how 它是值更新,是否可以不调用 setter?
这是映射的超级 class:
@MappedSuperclass
public abstract class SuperEntity implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1125783654888232605L;
/**
* The time the entry was created
*/
@Column(name = "CREATED")
private Timestamp created;
/**
* The date the entry was edited
*/
@Column(name = "EDITED")
@Version
private Timestamp edited;
是的。 JPA 实现不需要一些 属性 侦听器或代理来让您的 class 检测值已通过 setter 更新。他们如何检测托管实例的更改可能取决于实现,但支持通过直接访问而不是 getter/setter 更新字段。例如,可以保留通过持久性管理器获得的实例的副本,并且在完成事务或发出提交时,您可能已对其进行更改的托管实例将与它们的原始实例进行比较,并将对数据库的更新发布为必要的。
实际上,可以通过以下注解明确指定如何访问实体 class:https://docs.oracle.com/javaee/7/api/javax/persistence/Access.html
相反,可能有些属性不受字段支持,而是具有计算值的 getter。使用 属性 访问时,这些也会导致在从代码创建数据库时生成列,并在持久化或合并实体时生成 inserting/updating 值。
所以简而言之,仅仅调用 setter 并不能将托管实体中的 属性 或持久字段标记为 "dirty"。如果您可以直接访问一个字段并对其进行更改,那也会导致更新。
带有 @Version
注释的字段将由 hibernate 自动控制,并用于其 optimistic locking 功能。
因此,当您保存实体时,Hibernate 本身会自动设置该字段。
检查这些东西。
- 您的实体可能正在实施某种可审核接口
- 您的字段可能有@Version 注释
在第一种情况下,你已经弄清楚了接口的用法并且你可以理解它 在第二种情况下,它是 EJB 和 Hibernate 中的默认行为和预期行为。
我在谷歌搜索后得到了这个link它可能对你有用
这不是什么大事,你可以轻松克服