Spring-Data 中的父对象不获取子对象
Posted
技术标签:
【中文标题】Spring-Data 中的父对象不获取子对象【英文标题】:Child objects aren't fetched with parent object in Spring-Data 【发布时间】:2020-01-26 21:32:53 【问题描述】:我对 Hibernate 很陌生,我已经在父对象和子对象之间设置了 @OneToMany 双向关系,并期望当我将所有内容保存在数据库中时,将父对象设置为子对象(因为子对象是关系),当我使用 ORM 获取父对象时,我希望也获取一个子对象,但作为回报,我看到零个子对象。
据我在互联网上阅读的内容所了解的,当我将子对象作为与父级的关系的所有者时,完整的 ORM 应该会根据预定义的关系映射来连接两个对象.这些信息正确吗?
@Entity
@Table(name = "stream")
@SequenceGenerator(name = "sequence", sequenceName = "stream_id", allocationSize = 1)
public class StreamEntity extends EntityWithId
// @MappedSuperclass with ID
@Column(name = "request_id")
@OneToMany(
mappedBy = "streamEntity",
fetch = FetchType.LAZY
)
private List<RequestEntity> requestEntities = new ArrayList<>();
// getters setters
@Entity
@Table(name = "request")
@SequenceGenerator(name = "sequence", sequenceName = "request_id", allocationSize = 1, initialValue = 1)
public class RequestEntity extends EntityWithId
// @MappedSuperclass with ID
@JoinColumn(name = "stream_id")
@ManyToOne(fetch = FetchType.LAZY)
private StreamEntity streamEntity;
// getters setters
一些测试:
@Test
public void createStreamWithSeveralStreamTargetsAndDeleteStream()
List<StreamEntity> streamEntities = createStream(1); // stream object is persisted here
List<RequestEntity> requestEntitySave = createRequest(1, streamEntityCheck);
assertEquals(1, requestEntitySave.size()); // request entity is persisted with the stream object into the database
List<StreamEntity> streamEntities = streamDao.findAll();
assertEquals(1, streamEntities.size());
StreamEntity streamEntity2 = streamEntities.get(0);
streamEntity2.getRequestEntities(); - this collection shows 0
我错过了什么?
更新: 正如@Alan Hay 建议的那样,我已经在我的测试中添加了一个@Persistent 上下文,现在它看起来像这样:
@PersistenceContext
private EntityManager em;
@Test
public void createStreamWithSeveralStreamTargetsAndDeleteStream()
List<StreamEntity> streamEntities = createStream(1); // stream object is persisted here
List<RequestEntity> requestEntitySave = createRequest(1, streamEntityCheck);
assertEquals(1, requestEntitySave.size()); // request entity is persisted with the stream object into the database
em.clear();
List<RequestEntity> requestEntities = requestDao.findAll();
assertEquals(1, requestEntities.size()); // retirns zero objects
List<StreamEntity> streamEntities = streamDao.findAll();
assertEquals(1, streamEntities.size());
StreamEntity streamEntity2 = streamEntities.get(0);
streamEntity2.getRequestEntities();// this collection shows 0
完成此操作后,我在 requestDao.findAll(); 上得到零个对象;步。我已在上一步中提交了这些更改,为什么我无法获取此实体?
【问题讨论】:
看这里:Difference between FetchType LAZY and EAGER in Java Persistence API? 感谢您的回答,我已经了解了 fetch 类型之间的区别,据我了解 FetchType.LAZY 它应该至少返回代理对象,但它什么也不返回。跨度> 【参考方案1】:由于一级缓存的概念,您创建和保存的初始对象与您加载的对象是同一个实例。由于您没有将创建的请求实体添加到内存模型中,而只是将其持久化到数据库中,因此内存模型中不存在关系。
要获得所需的结果,您需要清除保存和重新加载之间的持久性上下文。
@Test
public void createStreamWithSeveralStreamTargetsAndDeleteStream()
List<StreamEntity> streamEntities = createStream(1);
List<RequestEntity> requestEntitySave = createRequest(1, streamEntityCheck);
assertEquals(1, requestEntitySave.size());
//you need to clear the persistence context here
//now a db query should execute.
//Inject the entitymanager to your test @PersistenceContext EntityManager em;
em.clear();
List<StreamEntity> streamEntities = streamDao.findAll();
assertEquals(1, streamEntities.size());
StreamEntity streamEntity2 = streamEntities.get(0);
streamEntity2.getRequestEntities(); - this collection shows 0
【讨论】:
谢谢你的回答,我还有几个问题。我正在使用带有这种花哨的模糊 CRUD 方法的 spring-data,我认为他们正在做所有这些事情,即开箱即用地清除上下文等,对吗?我是否需要对 spring 数据执行任何其他配置才能使其按预期工作? 一级缓存由hibernate管理,无法绕过。通常你会想要它。确保内存模型的一致性是您的责任。以上是关于Spring-Data 中的父对象不获取子对象的主要内容,如果未能解决你的问题,请参考以下文章