2015-02-24 92 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