更新/编辑Hibernate实体无法正常工作

时间:2015-02-24 11:33:22

标签: java hibernate spring-mvc selenium

我在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]。也许有一些我不知道的设计问题......我错过了什么?

更新

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

merge()解决了这个问题。

1 个答案:

答案 0 :(得分: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());
}