Hibernate不会完全刷新实体子级 [英] Hibernate does not refresh entity childs completely
问题描述
我使用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.refresh(e)
似乎不够,因为它没有似乎无法清除一级缓存。因此,如果要清除一级缓存,则应尝试清除 persistenceContext
。没有保证,但是您可以尝试: entityManager.clear()
If you want to cache the entityManager, entityManager.refresh(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屋!