我认为您不应该使用hibernate会话事务方法,而让spring这样做。
将此添加到您的spring conf:
<bean id="txManager" > <property name="sessionFactory" ref="mySessionFactory" /></bean><bean id="transactionTemplate" > <property name="transactionManager" ref="txManager"/></bean>
然后我将修改您的测试方法以使用spring事务模板:
public static void main(String[] args) { // init here (getting dao and transaction template) transactionTemplate.execute(new TransactionCallback() { @Override public Object doInTransaction(TransactionStatus status) { // do your hibernate stuff in here : call save, list method, etc } }}
附带说明一下,@OneToMany关联默认情况下是惰性的,因此您无需将其注释为惰性。(@ * ToMany默认为LAZY,@ *ToOne默认为EAGER)
编辑:从hibernate的角度来看,这就是现在正在发生的事情:
- 开放会话(从事务开始)
- 保存用户并将其保留在会话中(请参阅会话缓存作为实体哈希图,其中键是实体ID)
- 保存事件并将其保留在会话中
- 保存另一个事件并将其保留在会话中
…与所有保存 *** 作相同…
然后加载所有用户(“来自用户”查询)
那时,hibernate看到它在其会话中已经有该对象,因此丢弃从请求中获取的对象,然后从会话中返回该对象。
- 您会话中的用户未初始化其事件集合,因此您将获得null。
- …
以下是增强代码的一些要点:
- 在模型中,当不需要集合排序时,对集合使用Set而不是List(私有Set事件,而不是私有List事件)
- 在模型中,键入您的集合,否则hibernate将不会获取哪个实体(私有Set
事件) - 当您设置双向关系的一侧,并且希望在同一事务中使用该关系的mappedBy一侧时,请设置双方。Hibernate不会在下一次发送之前为您执行此 *** 作(当会话是从db状态返回的新视图时)。
因此,要解决上述问题,可以在一个事务中进行保存,而在另一事务中进行加载:
public static void main(String[] args) { // init here (getting dao and transaction template) transactionTemplate.execute(new TransactionCallback() { @Override public Object doInTransaction(TransactionStatus status) { // save here } } transactionTemplate.execute(new TransactionCallback() { @Override public Object doInTransaction(TransactionStatus status) { // list here } }}
或设置双方:
...event1.setUser(user);...event2.setUser(user);...user.setEvents(Arrays.asList(event1,event2));...
(也别忘了解决上面的代码增强点,“不设置列表,集合键入”)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)