我使用Hibernate 5.1.0.Final.我的GenericDAO
类的主要方法:
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> images
的Item
实体。
@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
-它包含最新的图像列表。然后,我在另一个REST方法中加载具有相同ID的Item
,该方法删除旧图像并添加新图像,更改标题。稍后,如果尝试在第一个REST方法中用genericDAO.find(id)
重新加载Item
,我得到过时的图像-他们没有再次选择,而Item
标题检索正确。
如何从数据库中获得完全刷新的实体及其查尔兹实体?
2条答案
按热度按时间bq3bfh9z1#
您缓存
entityManagers
的方式是正确的,因为在request
作用域中,但是您可以注意到它有副作用。使用Hibernate的一级缓存。
为什么不按事务使用不同的
entityManager
示例?通过用户请求示例化EntityManager应该不会太昂贵。
如果你想缓存entityManager,
entityManager.refresh(e)
似乎不够,因为它似乎没有清除一级缓存。所以,如果你想清除一级缓存,你应该尝试清除persistenceContext
。不保证,但你可以尝试:entityManager.clear()
就我个人而言,我更喜欢使用独特的
entityManager
事务示例的解决方案,它便宜而且设计清晰。2ul0zpep2#
当数据库同时发生更改时,Hibernate的一级/二级缓存与可见性无关。您需要查看隔离级别,
REPEATABLE_READ
是最常见的,应该是您的问题来源。您可以“锁定”实体以防止修改:
根据DB / Hibernate适配器,可能会导致
SELECT .... FOR UPDATE
。