当前位置: 首页 > 知识库问答 >
问题:

EclipseLink 不会检测在 @PreUpdate 内部使用反射进行的更新

水睿
2023-03-14

我想在我的应用中注册对某个实体所做的更改;我希望它在JPA的不同实现之间是可移植的,所以我不能使用Envers(Hibernate)或History Policy(EclipseLink)这样的框架。

所以我向我的实体添加了一个 changeLog 字段,我正在使用带有@PreUpdate@PrePersist注释的实体侦听器来更新此字段。

问题是,我想使用注释来指示应该存储这些更改的字段,而不是使用字段的固定名称。当我使用反射来更新这个字段而不是直接使用set方法时,Eclipse Link似乎无法检测到变更日志字段中的更改,因此,它不在生成的UPDATE语句中

@PreUpdate
@PrePersist
public void updateChangeLog(Object auditable) throws IllegalAccessException {
    Field[] fields = auditable.getClass().getDeclaredFields();
    Field changeLogField = null;

    for (Field field : fields) {
        if (field.getAnnotation(ChangeLog.class) != null) {
            field.setAccessible(true);
            changeLogField = field;
        }
    }


    String changeLog = generateChangeLog();


    // This works
    // ((MyEntity)auditable).setChangeLog(changeLog);

    // This doesn't work!
    changeLogField.set(auditable, changeLog);
}

这是EclipseLink中的一个错误还是预期的行为?有没有办法将< code>changelog字段标记为dirty,以便EclipseLink更新它的值?

共有1个答案

康赞
2023-03-14

出于性能原因,EclipseLink的编织默认使用变更跟踪。这意味着直接对字段进行的更改将不会生效。您可以使用访问器方法来更改这些值,这些方法将被更改监听器获取。否则,您必须关闭更改跟踪,如下所述:http://eclipse . org/eclipse link/documentation/2.5/JPA/extensions/a _ change tracking . htm

或关闭编织。

 类似资料:
  • 问题内容: 我在StackOverflow上遇到了类似的问题,尝试了解决方案,但没有找到答案。 我正在使用一种相当通用的JPA策略来设置某些实体的上次修改时间。设置列和字段,然后使用标记方法,并将其设置为等于当前时间。 问题是,我可以在调试器中看到正在调用该方法并且该字段正在更新,但是在我的数据库日志中,我仅看到一个SQL调用,以UPDATE更改字段,其中不包含timestamp字段的UPDATE

  • 问题内容: 在我的应用程序中,我定义了以下类: 如果我尝试将新帖子添加到论坛实体,则数据库将通过回调正确更新字段。但是,如果我尝试使用以下代码更新发布实体: 仅帖子数据被更新,字段值不变。我认为方法应该有效,并更新论坛实体。这是错误还是我错过了什么? 问题答案: 这不是错误,即使快速尝试也可以达到您预期的效果。不利的消息是由于以下原因,不能保证它能正常工作: 从JPA 2.0规范的第93页: 通常

  • 问题内容: 具体来说,我正在尝试为需要用于在Windows和Unix上构建路径的方法创建单元测试。该代码必须在两个平台上都可以运行,但是当我尝试更改此static final字段时,却遇到了JUnit错误。 任何人都知道发生了什么事吗? 当我这样做时,我得到 有什么想法吗? 问题答案: 从文档中: 如果基础字段是final,则该方法将为该字段成功地抛出除非, 并且该字段是非静态的 。 因此,在第一

  • 我有一个Jqgrid,Dinamicly生成如下所示的选择:

  • 我在试验Eclipselink。我正在尝试更新数据库中的一个现有实体。JPA实体只有公共字段,字段使用JPA注释进行注释。代码使用加载实体。 代码创建JPA实体的实例,为实体的公共字段赋值,并调用EntityManager.merge(entity)方法。Eclipselink不更新数据库记录。我启用了log来查看Eclipselink是否发出SQL语句。 Eclipselink不发出任何upda

  • 问题内容: 有人可以验证内部连接对PL SQL中的UPDATE语句是否有效吗?例如 问题答案: 该synthax在Oracle SQL中不起作用。 在Oracle中,如果表是“键保留”的,则可以更新联接,即: 假设这是的主键,则此连接是可更新的,因为对于A的每一行,B 最多 只有一行,因此该更新是确定性的。 在您的情况下,由于更新后的值不依赖于另一个表,因此您可以使用具有EXIST条件的简单更新,