Hibernate:保存新实体后没有会话

时间:2012-04-03 07:12:32

标签: spring hibernate wicket

我创建了一个新实体,第一次存储它,然后想要访问相关类的集合:

 @Override
 protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {           
        final E entity = (E) form.getModelObject();
        getDao().save(entity); //calls session.saveOrUpdate(entity)
        LOG.debug("Saved entity " + entity);
        LOG.debug("Show collections " + entity.getField().getListOfSomething());
        parent.replaceContentPanel(parent.getDetailsPanel(parent.createReloadableModel(entity)), target);
 }

我在第二行记录时遇到以下错误:

org.hibernate.LazyInitializationException: 
failed to lazily initialize a collection of role: 
no session or session was closed

我也试过

Hibernate.initialize(getDetailsModel().getObject().getField().getListOfSomething());

这会导致不同的错误:

org.hibernate.HibernateException: collection is not associated with any session

调试时这并不奇怪我可以看到集合代理没有与之关联的会话。

我正在使用Spring框架附带的'openSessionInView'过滤器。当我想要更新现有实体时,代码工作正常。当我在集合上设置fetchType时,它也有效:

@OneToMany(mappedBy = "field", fetch = FetchType.EAGER)
private List<E> listOfSomething= new ArrayList<E>();

我真的需要将此设置为EAGER吗?我想避免这种情况,并希望能绕过它。有没有办法将新存储的实体与Hibernate会话相关联?我尝试过session.load(entity)session.merge(entity)都没有成功。

我的实体看起来像这样:

@Entity class A { 
    @ManyToOne B b;
}

@Entity class B {     
   @OneToMany(mappedBy = "b") List<A> aList;
   @OneToMany(mappedBy = "b") List<C> cList;
}

@Entity class C {
   @ManyToOne B b;
}

我正在做的是创建c = new C(),从b中选择DropDownChoice,然后在提交时我要保留getDao().save(c)。提交后,我想在通过ajax加载的另一个面板上显示我的新实体。例如,我想显示c.getB().getAList(),这就是发生异常的地方,因为我从b中选择的DropdownChoice是一个分离的实体而且它的aList未被提取且无法获取懒得加载。

我无法弄清楚如何将仍然存在的会话放入我的新C实例中。

以下是我web.xml

的更多信息
<filter>
    <filter-name>opensessioninview</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>        
</filter>
<filter-mapping>
    <filter-name>opensessioninview</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

2 个答案:

答案 0 :(得分:0)

适当的解决方法是在访问集合之前合并()包含集合的对象。

答案 1 :(得分:-1)

我找到了一个变通方法,允许我强制加载我知道我需要的集合Hibernate.initialize(...)

final ListModel<B> listModel = new ListModel<B>(bList);
for (final B b : bList) {
   Hibernate.initialize(b.getAList());
}
add(new DropDownChoice<B>("b", listModel, new ChoiceRenderer<B>("name", "id")));

当我将此代码段中的第2-4行添加到我的表单中时,我稍后可能为B的新实例选择的C的所有实例都将具有A的初始化列表。

我对此感到高兴。我仍然希望能够根据需要将对象附加到hibernate会话。