Hibernate 不会完全刷新实体子项

Hibernate does not refresh entity childs completely

我使用 Hibernate 5.1。0.Final。我的GenericDAOclass主要方法:

public T save(T entity) {
    entityManager.getTransaction().begin();
    entityManager.persist(entity);
    entityManager.getTransaction().commit();
}

public T find(Long entityId) {
    T e = (T) entityManager.find(type, entityId);
    entityManager.refresh(e);
    return e;
}

我有 Item 个实体,其中包含 List<Image> images

@Entity
@Table(name="item")
public class Item extends GenericEntity {

    @Column(name="title")
    String title;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "item", cascade = {CascadeType.ALL}, orphanRemoval = true)
    @NotFound(action = NotFoundAction.IGNORE)
    List<Image> images;

    @Version
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name="version")
    Date version;

}


@Entity 
@Table(name="image")
public class Image extends GenericEntity {

    @ManyToOne
    @JoinColumn(name="item")
    Item item;

    @Column(name="image_name")
    String imageName;

}

首先,我使用 genericDAO.find(id) 方法加载 Item - 它包含 up-to-date 图像列表。然后我在另一个 REST 方法中加载具有相同 ID 的 Item,该方法删除旧图像并添加新图像,更改标题。稍后,如果尝试在第一个 REST 方法中使用 genericDAO.find(id) 重新加载 Item,我会得到过时的图像 - 在正确检索 Item 标题时它们不会再次被选中。

如何从数据库中获取完全刷新的实体及其子实体?

您缓存 entityManagers 的方式是正确的,因为在 request 范围内,但您会注意到它有副作用。
你用的是Hibernate的一级缓存
为什么不按事务使用不同的 entityManager 实例?
根据用户请求实例化 EntityManager 应该不会很昂贵。

如果要缓存entityManager,entityManager.refres‌​h(e)似乎不​​够,因为它似乎没有清除一级缓存。所以,如果你想清除一级缓存,你应该尝试清除persistenceContext。不能保证,但您可以尝试:entityManager.clear()

就个人而言,我更喜欢按事务使用唯一 entityManager 实例的解决方案。它便宜且设计清晰。