简体   繁体   中英

ye olde “org.hibernate.NonUniqueObjectException”… I am stumped on this one

Here's the error:

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.project.lmu.data.entity.Company#02K]
    org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:638)
    org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:305)
    org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:246)
    org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:112)
    org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
    org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:685)
    org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:677)
    org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:252)
    org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392)
    org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335)
    org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
    org.hibernate.engine.Cascade.cascade(Cascade.java:161)
    org.hibernate.engine.Cascade.cascade(Cascade.java:127)
    org.hibernate.event.def.DefaultSaveOrUpdateEventListener.cascadeOnUpdate(DefaultSaveOrUpdateEventListener.java:376)
    org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:350)
    org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:246)
    org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:112)
    org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
    org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:685)
    org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:677)
    org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:252)
    org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392)
    org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335)
    org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
    org.hibernate.engine.Cascade.cascade(Cascade.java:161)
    org.hibernate.engine.Cascade.cascade(Cascade.java:127)
    org.hibernate.event.def.DefaultSaveOrUpdateEventListener.cascadeOnUpdate(DefaultSaveOrUpdateEventListener.java:376)
    org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:350)
    org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:246)
    org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:112)
    org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
    org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:685)
    org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:677)
    org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:673)
    com.project.lmu.data.dao.hibernate.AbstractHibernateDAO.saveOrUpdate(AbstractHibernateDAO.java:172)
    com.project.lmu.data.tx.AbstractTxService.update(AbstractTxService.java:68)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    java.lang.reflect.Method.invoke(Method.java:597)
    org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318)
    org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    $Proxy48.update(Unknown Source)
    com.project.lmu.data.service.impl.CoworkerServiceImpl.genUpdateNomination(CoworkerServiceImpl.java:175)
    com.project.lmu.controller.coworkerNom.CoworkerController.genUpdateNomination(CoworkerController.java:305)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    java.lang.reflect.Method.invoke(Method.java:597)
    org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:212)
    org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:900)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:311)
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116)
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:101)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:182)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:125)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:173)
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)

Now here's the method that's failing:

public void genUpdateNomination(int nominationId, int statusId, String generalistComment, int generalistId) {
        CoworkerNom nom = coworkerNomTxService.findById(nominationId);
        Status status = statusTxService.findById(statusId);
        if (!(nom.getStatus() == status && nom.getGeneralistComment().equals(generalistComment))) {
            if (statusId == 2) {
                //Approved so do email
            }

            if (statusId == 3) {
                //Does Not Proceed so do email
            }

            if (statusId == 4) {
                //Incomplete so do email
            }

            Employee generalist = employeeTxService.findById(generalistId);

            nom.setGeneralist(generalist);
            nom.setGeneralistComment(generalistComment);
            nom.setStatus(status);
            nom.setUpdatedBy(generalist);
            coworkerNomTxService.update(nom);
        }
    }

Now I have boiled it down to entity Employee and Nomination 's Nominator and Nominee (which are Employee objects as well). Here is Nomination :

@Entity(name = "Nomination")
@Table(name = "NOMINATION")
@DiscriminatorColumn(name="CATEGORY_CODE", discriminatorType = DiscriminatorType.STRING, length = 1)
@Inheritance(strategy=InheritanceType.JOINED)

public /*abstract*/ class Nomination extends AuditableEntity {

    @Id
    @Column(name = "NOM_ID", insertable = true, updatable = true,
            nullable = false)
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinColumn(name = "NOMINATOR_ID", referencedColumnName = "EMP_ID")
    @Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE,
            org.hibernate.annotations.CascadeType.MERGE})
    private Employee nominator = null;


    @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinColumn(name = "GENERALIST_ID", referencedColumnName = "EMP_ID", nullable = true)
    @Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE,
            org.hibernate.annotations.CascadeType.MERGE})
    private Employee generalist = null;

And here is Employee :

@Entity(name = "Employee")
@Table(name = "EMPLOYEE")
public class Employee implements Serializable {
    @Id
    @Column(name = "EMP_ID", insertable = true, updatable = false, nullable = false)
    private int id;

    @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinColumn(name = "COMPANY_CODE", referencedColumnName = "COMPANY_CODE")
    @Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE,
            org.hibernate.annotations.CascadeType.MERGE})
    private Company company = null;

Now these objects have worked with a TON of methods in my applications. In fact I just encountered this error on my last method/addition in order to go to testing/test-cases mode.

Let me know if I have to paste more methods in. I have no idea what could cause this. The only new thing here is setting the generalist .

I encountered the same error once. It comes up in many to one or many-many relationship, main reason being an object is open in one session, but it is referenced to another object in some other session. I hope this reference helps.

I fixed this after trying quite a few things but what ended up working was replacing this:

       coworkerNomTxService.update(nom);

with merge() as so:

       coworkerNomTxService.merge(nom);

I'm posting here so hopefully if you get that same error you will try this method first. If not try to check if CascadeType is set at ALL and.

First thing I always do is calling session.getStatistics().getEntityKeys() before the session.update() method call and see if there are any duplicate object. If yes, trace it down using the same method.

Secondly, make sure your updated objects' children collection (if any) didn't have the same id.

Hope it helps

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM