【问题标题】:Hibernate: No session after save of new entity休眠:保存新实体后没有会话
【发布时间】:2012-04-03 07:12:31
【问题描述】:

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

 @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(),从DropDownChoice 中选择b,然后在提交时我想坚持getDao().save(c)。提交后,我想在通过 ajax 加载的不同面板上显示我的新实体。例如我想显示c.getB().getAList(),这就是发生异常的地方,因为我从DropdownChoice中选择的b是一个分离的实体,它的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>

【问题讨论】:

  • 您正在使用的“openSessionInView”过滤器,事务何时/何地开始和提交?
  • 您的实体看起来如何?例如。保存操作会级联到集合吗?
  • 请包含 web.xml 的相关部分(调度程序 servlet 和 OpenSessionInView 过滤器)
  • 您使用什么 IModel 实现来保存实体?您是否尝试过使用 LoadableDetachableModel?
  • 我正在结合 CompoundPropertyModel 使用 LoadableDetachableModel(我自己的实现主要受“Wicket in Action”的启发)

标签: spring hibernate wicket


【解决方案1】:

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

【讨论】:

  • 我尝试合并原始实体,我尝试仅合并包含集合的相关实体。两者都不起作用-.-
【解决方案2】:

我找到了一种解决方法,可以让我使用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")));

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

对此我只满意一半。我仍然希望能够根据需要将对象附加到休眠会话。

【讨论】:

    猜你喜欢
    • 2020-02-16
    • 2012-09-09
    • 1970-01-01
    • 2014-09-12
    • 1970-01-01
    • 1970-01-01
    • 2016-12-27
    • 1970-01-01
    • 2021-12-04
    相关资源
    最近更新 更多