Hibernate 不会完全刷新实体子项
Hibernate does not refresh entity childs completely
我使用 Hibernate 5.1。0.Final。我的GenericDAO
class主要方法:
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.refresh(e)
似乎不够,因为它似乎没有清除一级缓存。所以,如果你想清除一级缓存,你应该尝试清除persistenceContext
。不能保证,但您可以尝试:entityManager.clear()
就个人而言,我更喜欢按事务使用唯一 entityManager
实例的解决方案。它便宜且设计清晰。
我使用 Hibernate 5.1。0.Final。我的GenericDAO
class主要方法:
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.refresh(e)
似乎不够,因为它似乎没有清除一级缓存。所以,如果你想清除一级缓存,你应该尝试清除persistenceContext
。不能保证,但您可以尝试:entityManager.clear()
就个人而言,我更喜欢按事务使用唯一 entityManager
实例的解决方案。它便宜且设计清晰。