2010-06-21 23 views
3

在从数据库中,我得到下面的异常删除的实体相关联:org.hibernate.HibernateException:非法尝试集合有两个打开的会话

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) 

我挖深,并试图从众多的解决方案休眠论坛,但我仍然不知道发生了什么事以及会话在哪里打开。发生此问题的条件:

第一个: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> 

二:三层架构。这里是类和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; 
} 

public class TagDAO extends HibernateDaoSupport implements ITagDAO { 

@Override 
public void create(Tag tag) { 
    getHibernateTemplate().save(tag); 
} 

@Override 
public Tag getTag(String name){ 
    Tag group = null; 

    DetachedCriteria criteria = DetachedCriteria.forClass(Tag.class); 
    criteria.add(Restrictions.eq("name", name)); 
    List<Tag> tags = getHibernateTemplate().findByCriteria(criteria); 
    if ((tags != null) && (tags.size() > 0)) { 
    group = (Tag)tags.get(0); 
    } 
    return group; 
} 

@Override 
public Tag getTag(Long id){ 
Tag group = null; 
List<Tag> groups = getHibernateTemplate().find(
"from Tag where id = ?", id); 
if ((groups != null) && (groups.size() > 0)) { 
group = (Tag)groups.get(0); 
} 
return group; 
} 

@Override 
public List<Tag> getTags(){ 
List<Tag> ret = getHibernateTemplate().find("from Tag"); 
System.out.println("Dao got "+ret.size()+" tags"); 
return ret; 
} 

@Override 
public Integer getTagCount() { 
DetachedCriteria criteria = DetachedCriteria.forClass(Tag.class); 
criteria.setProjection(Projections.rowCount()); 
return (Integer)(getHibernateTemplate().findByCriteria(criteria).get(0)); 
} 

@Override 
public void delete(Tag group) { 
getHibernateTemplate().delete(group); 

} 

@Override 
public void update(Tag group) { 

getHibernateTemplate().update(group); 

} 

@Override 
public List<Tag> getTags(Integer first, Integer resultsPerPage, 
String order, Boolean asc) { 

DetachedCriteria criteria = DetachedCriteria.forClass(Tag.class); 
if (asc){ 
criteria.addOrder(Order.asc(order)); 
}else{ 
criteria.addOrder(Order.desc(order)); 
} 
return (List<Tag>)getHibernateTemplate().findByCriteria(criteria, first, resultsPerPage); 
} 
} 

public class ProjectService implements IProjectService { 

// Beans used by this service. 
private IProjectDAO projectDao; 
private ITagDAO tagDao; 

@Override 
public void createProject(Project project) throws AlreadyExistsException { 
if (projectDao.getProject(project.getName()) != null) { 
    throw new AlreadyExistsException(); 
} 
projectDao.addProject(project); 
} 

@Override 
public List<Project> getProjects(Integer first, Integer howMany, String order, 
    boolean asc) { 
return projectDao.getProjects(first, howMany, order, asc); 
} 

@Override 
public Integer getProjectCount(){ 
return projectDao.getProjectCount(); 
} 

@Override 
public List<Project> getProjects() { 
return projectDao.getAllProjects(); 
} 

@Override 
public void deleteProject(Long id) { 
projectDao.removeProject(id); 
} 

@Override 
public List<Tag> getTags() { 
return tagDao.getTags(); 
} 

@Override 
public Tag getTag(String name){ 
return tagDao.getTag(name); 
} 
@Override 
public void createTag(Tag tag) throws AlreadyExistsException { 
if (tagDao.getTag(tag.getName()) != null) { 
    throw new AlreadyExistsException(); 
} 
tagDao.create(tag); 
} 
@Override 
public void deleteTag(Long id) { 
    tagDao.delete(tagDao.getTag(id)); 
} 
@Override 
public void updateTag(Tag tag) { 
tagDao.update(tag); 

} 
} 

@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()); 
} 

} 

最后的网页:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets"  xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.prime.com.tr/ui"> 
<ui:composition template="/templates/template.xhtml"> 
    <ui:define name="head"> 
    <title>Tags</title> 
    <link rel="stylesheet" type="text/css" href="#{facesContext.externalContext.requestContextPath}/styles/style.css"/> 
    </ui:define> 
    <ui:define name="content"> 
    <h:form name="commandForm"> 
    <p:dataTable var="tag" name="tagsList" value="${tagPresenter.tags}" paginator="true" rows="10" > 
    <p:column sortBy="#{tag.id}"> 
     <f:facet name="header"> 
     <h:outputText value="Id" /> 
     </f:facet> 
     <h:outputText value="#{tag.id}" /> 
    </p:column> 
    <p:column sortBy="#{tag.name}"> 
     <f:facet name="header"> 
     <h:outputText value="Name" /> 
     </f:facet> 
     <h:outputText value="#{tag.name}" /> 
    </p:column> 
     <p:column> 
     <h:commandLink action="#{tagDisplayer.showTag}" value="Modify"> 
     <f:setPropertyActionListener target="#{tagDisplayer.tag}" value="#{tag}"/> 
     </h:commandLink> 
     <h:commandLink action="#{tagPresenter.deleteTag}" value="Delete"> 
     <f:setPropertyActionListener target="#{tagPresenter.tag}" value="#{tag}"/> 
     </h:commandLink> 
    </p:column> 
    </p:dataTable> 
    </h:form> 
    <p:messages id="deletingError" showDetail="true"/> 
    </ui:define> 
</ui:composition> 
    </html> 

这个问题是怎么引起的?我该如何解决?

+4

'IProjectService' ??? Java和.net命名约定之间的差异之一在于不使用** I **前缀接口名称。只要发现它非常讨厌,当我看到这个在java代码中的任何地方。 – Shahzeb 2012-03-01 23:14:13

回答

0

查看Spring文档中的HibernateTemplate chapter。看看实现一个回调方法来访问会话。

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文档中提到further down。在这种方法中,不要使用HibernateTemplate来删除对象,而是使用HibernateDaoSupport中的Session来处理删除。

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

对此的修正差异很大;它可以通过的问题,像

  • 坏会话处理您的框架配置引起
  • 坏级联设置,不正确的持久性设置
  • 忘记存储在数据库@ManyToOne关系的集合初始化。

请务必在映射/休眠配置中彻底检查这些情况 - 在浪费时间之前。 :D

+0

错误的级联设置+1 - 谢谢。 – HDave 2014-08-27 00:19:08

0

这可能是由致电session.disconnect()而不是session.close()造成的。

相关问题