Hibernate不会完全刷新实体子级 [英] Hibernate does not refresh entity childs completely

查看:95
本文介绍了Hibernate不会完全刷新实体子级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Hibernate 5.1.0.Final。我的 GenericDAO 类主要方法:

I use Hibernate 5.1.0.Final. My GenericDAO class main methods:

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;
}

我有个项目包含 List< Image>的实体图片

@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;

}

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

First, I load Item with genericDAO.find(id) method - it contains up-to-date list of images. Then I load Item with the same ID in another REST method which removes old images and adds new ones, changes title. Later, if try to reload Item with genericDAO.find(id) in the first REST method, I get outdated images - they aren't selected again while Item title is retrieved correctly.

如何使用其完全刷新的实体

How to get completely refreshed entity with its childs from a database?

推荐答案

您缓存 entityManagers 的方式是正确,因为在 request 范围内,但是它有副作用,您可以注意到。

您使用的是Hibernate的一级缓存。

为什么不按事务使用不同的 entityManager 实例?

通过用户请求实例化EntityManager并不昂贵。

Your way of caching your entityManagers is correct since in the request scope but it has side-effects as you can notice.
You use the level one cache of Hibernate.
Why don't use a distinct entityManager instance by transaction ?
It should not be expensive to instantiate a EntityManager by user request.

如果要缓存entityManager,则 entityManager.refres‌h(e)似乎不够,因为它没有似乎无法清除一级缓存。因此,如果要清除一级缓存,则应尝试清除 persistenceContext 。没有保证,但是您可以尝试: entityManager.clear()

If you want to cache the entityManager, entityManager.refres‌​h(e) seems not enough since it doesn't seem to clear the level one cache. So, if you want to clear the first level cache, you should try to clear the persistenceContext. No guarantee but you can try : entityManager.clear()

我个人更喜欢使用唯一的 entityManager 实例按交易记录。价格便宜而且设计清晰。

Personally, I prefer the solution using a unique entityManager instance by transaction. It's cheap and a clear design.

这篇关于Hibernate不会完全刷新实体子级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆