EclipseLink关于OneToOne关系的PreUpdate不持久

tar*_*aki 5 jpa eclipselink entitylisteners

我有一个执行的PreUpdate方法,但是在刷新entityManager时,相关实体上的更改不会持久保存。

以下是我的最小(非)工作示例:

实体

@Entity
@Table(name = "HOUSE")
public class House {

    @Id
    @Column(name = "ID")
    private long id;

    @OneToOne(cascade = {CascadeType.ALL})
    @JoinColumn(name = "INFO_ID")
    private HouseInfo info;

    @PreUpdate
    protected void komplettiereEingabeWerte() {
        info.setCode("TEST");
    }

    //getters and setters
}

@Entity
@Table(name = "HOUSE_INFO")
public class HouseInfo {

    @Id
    @Column(name = "ID")
    private long id;

    @Column(name = "CODE")
    private String code;

    //getters and setters
}
Run Code Online (Sandbox Code Playgroud)

测试用例

@Test
@Transactional(TransactionMode.ROLLBACK)
public void testPreUpdate() {
    House house = entityManager.find(House.class, 1L);
    house.setInfo(new HouseInfo());
    entityManager.flush();
    entityManager.clear();

    house = entityManager.find(House.class, 1L);
    assertEquals("TEST", house.getInfo().getCode());
}
Run Code Online (Sandbox Code Playgroud)

由于Code为null,因此由于最后一行的AssertionError导致测试失败。

我将EclipseLink 2.7.4版本与Oracle DB一起使用(内存Derby DB中也观察到了相同的行为),并且Test在SpringApplicationContext中与UnitilsJUnit4一起运行。

我该如何解决这个问题?谢谢。

cri*_*zis 0

JPA规范指出:

一般来说,可移植应用程序的生命周期方法不应调用 EntityManager 或查询操作、访问其他实体实例或修改同一持久性上下文中的关系。生命周期回调方法可以修改调用它的实体的非关系状态

那么,简单的答案是实体侦听器不能用于该任务。相反,在您的服务层中实现相关逻辑。