【问题标题】:Updating JPA entity with reflection does not work?使用反射更新 JPA 实体不起作用?
【发布时间】:2009-07-07 12:51:46
【问题描述】:

我有一个看起来像这样的实体:(我正在对网页进行编码,因此对于任何错误,我深表歉意)

@Entity
public class Entity {
    @Id
    private Long id;
    private String field;

    // Insert getters and setters here...
}

我尝试使用反射来操纵它:

Long id = 1;

Entity entity = myDao.getEntity(id);

entity.setField("set directly");

Field[] fields = entity.getClass().getDeclaredFields();

for (Field f : fields) {
    if (f.getName().equals("field")) {
        f.setAccessible(true);
        f.set(entity, "set using reflection");
        f.setAccessible(false);
    }
}

System.out.println(entity.getField());

这个程序打印“使用反射设置”。但是,在数据库中使用反射设置的值不会更新:

SELECT * FROM ENTITY WHERE ID = 1
ID     FIELD
1      set directly

这很奇怪。我可以发誓这曾经有效——但现在不行了。是不是真的不能使用反射来操作实体?

如果这很重要,我正在使用 EclipseLink 1.1.1。

【问题讨论】:

    标签: java reflection jpa


    【解决方案1】:

    通过反射改变实体类的值会带来很多问题。这是因为您正在处理一个持久性类,因此持久性 API 需要了解字段的更改。

    如果您通过反射进行更改,则持久性 API 可能不会知道这些更改。

    更好的解决方案是通过反射调用设置器。

    【讨论】:

    • 谢谢,现在可以了。我通过反射调用 setter 和 getter。我认为当 EclipseLink 的静态编织打开时,原始代码会中断,因为我确定直接操作用于工作的字段。不过,现在一切都很好。
    【解决方案2】:

    我很确定您的持久性框架提供的实体实际上是包装在另一个类中(可能与通过反射附加的东西相同)。通过反射直接改变场似乎不太可能奏效。您可能想检查是否有可以使用的(生成的)setter。虽然如果你走那条路,可能有人会问为什么你不允许调用者直接调用 setter?

    【讨论】:

    • 好问题!原因是我正在尝试使用类似我接受的答案来比较和更新我的实体:stackoverflow.com/questions/867442/…
    • 我不确定您的设计是否非常合理,但如果 EclipseLink 正在修改类并添加设置器,那么找到它们应该很容易,因为它们可能会遵循 POJO 约定(字段的设置器是 setField( ))
    【解决方案3】:

    您的类可能已被检测,而 setter 负责记录更改。我不熟悉 EclipseLink 来检查 myDao.getEntity(id); 返回的类是否是 EclipseLink 生成的子类的实际类。

    【讨论】:

      猜你喜欢
      • 2019-02-09
      • 1970-01-01
      • 2012-03-31
      • 2011-06-22
      • 2021-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多