Spring org.hibernate.HibernateException:非法尝试将集合与两个打开的会话关联

Spring org.hibernate.HibernateException:非法尝试将集合与两个打开的会话关联,spring,hibernate,jsf,Spring,Hibernate,Jsf,从数据库中删除实体后,我会出现以下异常: org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions at org.hibernate.collection.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:410) at org.hib

从数据库中删除实体后,我会出现以下异常:

org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
   at org.hibernate.collection.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:410)
   at org.hibernate.event.def.OnUpdateVisitor.processCollection(OnUpdateVisitor.java:43)
   at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101)
   at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61)
   at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55)
 at org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:123)
 at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:101)
 at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:52)
 at org.hibernate.impl.SessionImpl.fireDelete(SessionImpl.java:767)
 at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:745)
 at org.springframework.orm.hibernate3.HibernateTemplate$25.doInHibernate(HibernateTemplate.java:790)
 at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:372)
 at org.springframework.orm.hibernate3.HibernateTemplate.delete(HibernateTemplate.java:784)
 at org.springframework.orm.hibernate3.HibernateTemplate.delete(HibernateTemplate.java:780)
 at pl.edu.agh.adam.core.projects.dao.TagDAO.delete(TagDAO.java:98)
 at pl.edu.agh.adam.core.projects.ProjectService.deleteTag(ProjectService.java:109)
 at pl.edu.agh.adam.core.projects.web.TagPresenter.deleteTag(TagPresenter.java:97)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at com.sun.el.parser.AstValue.invoke(AstValue.java:234)
 at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
 at org.apache.myfaces.view.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:83)
 at javax.faces.component._MethodExpressionToMethodBinding.invoke(_MethodExpressionToMethodBinding.java:88)
 at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:100)
 at javax.faces.component.UICommand.broadcast(UICommand.java:120)
 at javax.faces.component.UIData.broadcast(UIData.java:708)
 at javax.faces.component.UIViewRoot._broadcastAll(UIViewRoot.java:890)
 at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:234)
 at javax.faces.component.UIViewRoot._process(UIViewRoot.java:1202)
 at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:623)
 at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:35)
 at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:143)
 at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:93)
 at javax.faces.webapp.FacesServlet.service(FacesServlet.java:189)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
 at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
 at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
 at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
 at java.lang.Thread.run(Thread.java:619)
我已经在hibernate论坛上深入挖掘并尝试了许多解决方案,但我仍然不知道发生了什么,也不知道会议在哪里开始。出现此问题的条件:

首先:
OpenSessionInViewFilter
——我在这里问过。一切似乎都很正常,但是第二天删除操作突然停止了,我所做的就是——我将一个未连接的类添加到一个未连接的包中

  <!-- Hibernate OpenSession Filter -->
  <filter>
   <filter-name>hibernateFilter</filter-name>
   <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
   <init-param>
    <param-name>singleSession</param-name>
    <param-value>false</param-value>
   </init-param>
   <init-param>
    <param-name>sessionFactoryBeanName</param-name>
    <param-value>sessionFactory</param-value>
   </init-param>
   </filter>
  <filter-mapping>
    <filter-name>hibernateFilter</filter-name>
   <url-pattern>*</url-pattern>
  </filter-mapping>

冬眠过滤器
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
单一会话
假的
sessionFactoryBeanName
会话工厂
冬眠过滤器
*
第二:三层架构。下面是类和JSF页面:

@Entity
@Table(name = "tag")
public class Tag implements Serializable {
private static final long serialVersionUID = 1L;
@ManyToMany(mappedBy = "tags", targetEntity = Project.class)
List<Project> projects = new ArrayList<Project>();
@Transient
public static final String PROP_ID = "id";
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "tag_id")
private Long id;
@Transient
public static final String PROP_NAME = "name";
@Column(name = "name", length = 25, unique = true)
private String name;
}
@实体
@表(name=“tag”)
公共类标记实现可序列化{
私有静态最终长serialVersionUID=1L;
@ManyToMany(mappedBy=“tags”,targetEntity=Project.class)
列表项目=新建ArrayList();
@短暂的
公共静态最终字符串PROP_ID=“ID”;
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
@列(name=“tag\u id”)
私人长id;
@短暂的
公共静态最终字符串PROP_NAME=“NAME”;
@列(name=“name”,长度=25,唯一性=true)
私有字符串名称;
}

public类TagDAO扩展了HibernateDaoSupport实现了ITagDAO{
@凌驾
公共无效创建(标记标记){
getHibernateTemplate().save(标记);
}
@凌驾
公共标记getTag(字符串名称){
标签组=null;
DetachedCriteria=DetachedCriteria.forClass(Tag.class);
标准。添加(限制。等式(“名称”),名称);
列表标记=getHibernateTemplate().findByCriteria(标准);
如果((tags!=null)&&(tags.size()>0)){
group=(Tag)tags.get(0);
}
返回组;
}
@凌驾
公共标记getTag(长id){
标签组=null;
列表组=getHibernateTemplate()。查找(
“来自id=?”的标记,id);
如果((groups!=null)&&(groups.size()>0)){
group=(标记)groups.get(0);
}
返回组;
}
@凌驾
公共列表getTags(){
List ret=getHibernateTemplate().find(“从标记”);
System.out.println(“Dao-got”+ret.size()+“tags”);
返回ret;
}
@凌驾
公共整数getTagCount(){
DetachedCriteria=DetachedCriteria.forClass(Tag.class);
criteria.setProjection(Projections.rowCount());
返回(整数)(getHibernateTemplate().findByCriteria(criteria).get(0));
}
@凌驾
公共无效删除(标记组){
getHibernateTemplate().delete(组);
}
@凌驾
公共无效更新(标记组){
getHibernateTemplate().update(组);
}
@凌驾
公共列表getTags(整数优先,整数结果每页,
字符串顺序,布尔值(asc){
DetachedCriteria=DetachedCriteria.forClass(Tag.class);
如果(asc){
标准.addOrder(Order.asc(Order));
}否则{
标准.addOrder(Order.desc(Order));
} 
返回(列表)getHibernateTemplate().findByCriteria(条件,第一,resultsPerPage);
}
}

公共类ProjectService实现IProjectService{
//此服务使用的bean。
私人IProjectDAO projectDao;
私人ITagDAO tagDao;
@凌驾
public void createProject(项目项目)引发AlreadyExistsException{
if(projectDao.getProject(project.getName())!=null){
抛出新的AlreadyExistsException();
}
projectDao.addProject(project);
}
@凌驾
public List getProjects(整数优先、整数多少、字符串顺序、,
布尔值(asc){
returnprojectdao.getProjects(首先,数量,订单,asc);
} 
@凌驾
公共整数getProjectCount(){
返回projectDao.getProjectCount();
}
@凌驾
公共列表项目(){
返回projectDao.getAllProjects();
}
@凌驾
公共项目(长id){
projectDao.removeProject(id);
}
@凌驾
公共列表getTags(){
返回tagDao.getTags();
}
@凌驾
公共标记getTag(字符串名称){
返回tagDao.getTag(名称);
}
@凌驾
public void createTag(标记标记)引发AlreadyExistsException{
if(tagDao.getTag(tag.getName())!=null){
抛出新的AlreadyExistsException();
}
tagDao.create(tag);
}
@凌驾
公共无效删除标记(长id){
tagDao.delete(tagDao.getTag(id));
}
@凌驾
公共无效更新标记(标记标记){
tagDao.update(tag);
}
}

@ManagedBean(name=“tagPresenter”)
@请求范围
公共类TagPresenter{
私有列表标签;
私人IProjectService项目服务;
私人标签;
公共无效集合标记(标记标记){
this.tag=tag;
}
公共标记getTag(){
返回标签;
}
公共TagPresenter(){
projectService=(IProjectService)ServiceFinder.getInstance()
.findBean(“项目服务”);
tags=projectService.getTags();
}
私有无效刷新(){
tags=projectService.getTags();
}
公共列表getTags(){
刷新();
返回标签;
}
公共void deleteTag(){
deleteTag(tag.getId());
}
}

最后,网页:


标签
这个问题是如何引起的,我如何解决它?

请查看Spring文档中的。请看一下如何实现回调方法来访问会话

public void delete(final Tag group) throws Exception {
    HibernateCallback callback = new HibernateCallback() {
        public Object doInHibernate(Session session) throws HibernateException, SQLException {
            Object groupObj = session.load(Tag.class, group.getId());
            session.delete(groupObj);
            return null;
        }
    };
    getHibernateTemplate().execute(callback);
}
如果以上不是您想要的,您仍然可以使用Spring文档中提到的传统方法。在这种方法中,不要使用HibernateTemplate来删除对象,而是使用HibernateDataSupport中的会话来处理删除

public void delete(Tag group) throws Exception {
    Session session = getSession(false);
    Object groupObj = session.load(Tag.class, group.getId());
    session.delete(groupObj);
}

对此的修复方法差别很大;这可能是由以下问题引起的:

  • 框架配置中的会话处理错误
  • 错误的级联设置、不正确的持久性设置
  • 忘记初始化存储在@ManyToOne数据库关系中的集合
确保彻底检查这些情况
@ManagedBean(name = "tagPresenter")
@RequestScoped
public class TagPresenter {

 private List<Tag> tags;
 private IProjectService projectService;
 private Tag tag;


 public void setTag(Tag tag) {
  this.tag= tag;
 }
 public Tag getTag() {
  return tag;
 }

 public TagPresenter() {
  projectService = (IProjectService)ServiceFinder.getInstance()
   .findBean("projectService");
  tags = projectService.getTags();
 }

 private void refresh() {
  tags = projectService.getTags();
 }

 public List<Tag> getTags() {
  refresh();
  return tags;
 }

 public void deleteTag() {
  projectService.deleteTag(tag.getId());
 }

}
public void delete(final Tag group) throws Exception {
    HibernateCallback callback = new HibernateCallback() {
        public Object doInHibernate(Session session) throws HibernateException, SQLException {
            Object groupObj = session.load(Tag.class, group.getId());
            session.delete(groupObj);
            return null;
        }
    };
    getHibernateTemplate().execute(callback);
}
public void delete(Tag group) throws Exception {
    Session session = getSession(false);
    Object groupObj = session.load(Tag.class, group.getId());
    session.delete(groupObj);
}