0

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.

Nimchip
  • 1,685
  • 7
  • 25
  • 50

3 Answers3

1

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.

Community
  • 1
  • 1
Nitin Chhajer
  • 2,299
  • 1
  • 24
  • 35
  • The only many-to-many relation here is Nomination-to-Employee(Nominee). This relationship has not given me any problems before and I have a lot of methods that deal with the relationship. It only happens here. I also saw this post before posting but there's nothing that helps me because this error can be super general. The problem is that I'm not trying to persist the object that the error indicates `Company`, in fact the only object I'm trying to "persist" is Nomination. Either way, thank you! – Nimchip Apr 17 '12 at 20:16
1

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.

Nimchip
  • 1,685
  • 7
  • 25
  • 50
  • BTW, why you have transaction inside of "genUpdateNomination" and not outside of it? You have several db-access operations, should be executed in one transaction to prevent reading of changed data. – Vadim Ponomarev Apr 18 '12 at 14:34
  • The method is part of a service class, so it is instantiating transaction classes in it and using them. I'm aware this can be bumped down to TX level, but because it is very specific for the service i chose to let it be. – Nimchip Apr 18 '12 at 18:04
0

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

Joshua H
  • 754
  • 8
  • 18