2015-02-24 67 views
0

我尝试了TeamTeamMembers上级联类型的所有组合,但仍然无法使用手动/ Selenium测试更新/编辑给定的TeamMember。这个问题似乎与休眠:休眠实体的更新/编辑无法正常工作

SEVERE: Servlet.service() for servlet [dispatcher] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DuplicateKeyException: A different object with the same identifier value was already associated with the session : [com.sprhib.model.TeamMember#1]; nested exception is org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [com.sprhib.model.TeamMember#1]] with root cause 
org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [com.sprhib.model.TeamMember#1] 
    at org.hibernate.engine.internal.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:617) 
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:301) 
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:244) 
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:109) 
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90) 
    at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:684) 
    at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:676) 
    at org.hibernate.engine.spi.CascadingActions$5.cascade(CascadingActions.java:235) 
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350) 
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293) 
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161) 
    at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:379) 
    at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:319) 
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:296) 
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161) 
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118) 
    at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:167) 
    at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:158) 
    at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:91) 
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:55) 
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1222) 
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425) 
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101) 
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177) 
    at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:584) 
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:757) 
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:726) 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:515) 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291) 
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) 
    at com.sun.proxy.$Proxy46.updateTeamMember(Unknown Source) 
    at com.sprhib.controller.TeamMemberController.editingTeamMember(TeamMemberController.java:75) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:483) 
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:777) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:706) 
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) 
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:646) 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
    at java.lang.Thread.run(Thread.java:745) 

基本上所有的更新/编辑操作不起作用。我需要所有的UI测试才能通过。 [我的项目] [1]。也许有一些我不知道的设计问题...我错过了什么?

UPDATE:

import com.sprhib.model.Team; 
import com.sprhib.model.TeamMember; 
import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.hibernate.Transaction; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Repository; 

import javax.transaction.Transactional; 
import java.util.Iterator; 
import java.util.List; 
import java.util.Set; 

@Repository 
@Transactional 
public class TeamMemberDAOImpl implements TeamMemberDAO { 

    @Autowired 
    private SessionFactory sessionFactory; 

    private Session getCurrentSession() { 
     return sessionFactory.getCurrentSession(); 
    } 
    private Session openSession(){ 
     return sessionFactory.openSession(); 
    } 

    public void addTeamMember(TeamMember teamMember) { 
     Iterator<Team> iterator = teamMember.getTeams().iterator(); 
     while(iterator.hasNext()){ 
      Team t = iterator.next(); 
      Team team = (Team) getCurrentSession().get(Team.class, t.getId()); 

      Set<TeamMember> teamMembers = team.getTeamMembers(); 
      teamMembers.add(teamMember); 
     } 
    } 

    public void updateTeamMember(TeamMember teamMember) { 
     // get all teams related to teamMember 
     // for each team: 
     //  if team doesn't have this team member then add 
     synchronized (this){ 
      Iterator<Team> iteratorTeams = teamMember.getTeams().iterator(); 
      while(iteratorTeams.hasNext()){ 
       Team t = iteratorTeams.next(); 
       Team team = (Team) getCurrentSession().get(Team.class, t.getId()); 

       Set<TeamMember> teamMembers = team.getTeamMembers(); 
       if(!teamMembers.contains(teamMember)){ 
        teamMembers.add(teamMember); 
       } 
      } 

     } 


//  no errors but teams is not updated 
     /*TeamMember tm = getTeamMember(teamMember.getId()); 
     tm.setName(teamMember.getName()); 
     tm.setTeams(teamMember.getTeams());*/ 
    } 

    public TeamMember getTeamMember(int id) { 
     TeamMember teamMember = (TeamMember) getCurrentSession().get(TeamMember.class, id); 
     return teamMember; 
    } 

    public void deleteTeamMember(int id) { 
     if(getTeamMember(id) != null){ 
      getCurrentSession().delete(getTeamMember(id)); 
     } 

    } 

    @SuppressWarnings("unchecked") 
    public List<TeamMember> getTeamMembers() { 
     return getCurrentSession().createQuery("from TeamMember").list(); 
    } 
} 

UPDATE2

合并()解决了这个问题。

+0

怎么样的NonUniqueObjectException? – mylenereiners 2015-02-24 11:39:17

+0

@RCola你可以请发表方法的身体()所有你使用交易注释..! – mady 2015-02-24 11:39:21

+0

我无法正确更新现有实体。我可以更新拥有'OneToMany'的组织。但是不可能对具有'ManyToMany'关系的'TeamMember'和'Team'做同样的事情。所有类型的异常都会抛出。 – 2015-02-24 11:51:36

回答

0

试试这个下面的代码就可以成功我不知道..

@Transactional(propagation=Propagation.REQUIRED,readOnly=false) 
public void updateTeamMember(TeamMember teamMember) { 
    // get all teams related to teamMember 
    // for each team: 
    //  if team doesn't have this team member then add 
    synchronized (this){ 
     Iterator<Team> iteratorTeams = teamMember.getTeams().iterator(); 
     while(iteratorTeams.hasNext()){ 
      Team t = iteratorTeams.next(); 
      Team team = (Team) getCurrentSession().get(Team.class, t.getId()); 

      Set<TeamMember> teamMembers = team.getTeamMembers(); 
      if(!teamMembers.contains(teamMember)){ 
       teamMembers.add(teamMember); 

       getCurrentSession().merge(teamMember); // IMPORTANT! 
       getCurrentSession().merge(team); // IMPORTANT! 
      } 
     } 

    } 

    TeamMember tm = getTeamMember(teamMember.getId()); 
    tm.setName(teamMember.getName()); 
    tm.setTeams(teamMember.getTeams()); 
} 
+0

有些记录只是做得很好。但是有一些是抛出'org.springframework.dao.DuplicateKeyException:具有相同标识符值的不同对象已经与会话相关联:[com.sprhib.model.TeamMember#3];嵌套的异常是org.hibernate.NonUniqueObjectException:具有相同标识符值的不同对象已经与会话相关联:[com.sprhib.model.TeamMember#3]' – 2015-02-24 19:13:47

+0

可能必须有'merge()'for TeamMember '但是如何知道何时合并? – 2015-02-24 19:25:55

+0

当一个新实体要存入数据库时​​,使用persist(),并且当一个现有实体是一个从数据库获取的实体时需要更新,然后使用merge()。但merge()也可以用于持久化新实体。请检查您是否尝试更新或保留实体以及您使用哪种方法进行持续更新。 – mady 2015-02-25 07:46:28