尝试将数据插入数据库时,出现了"org.hibernate.PersistentObjectException: detached entity passed to persist"的错误提示。

7

我正在尝试将一个实体类持久化到数据库中,为此我尝试了几种不同的类实现方式,但仍然遇到了错误(但错误不同)。我的实体类目前是这样的:

@Entity
@Table(name="pagina")
public class Pagina extends Entidade {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer Id;

    @Column(name = "nome", unique=true)
    private String nome;

    @Column(name = "titulo")
    private String titulo;

    @Column(name = "descricao")
    private String descricao;

    @OneToOne( cascade = {CascadeType.ALL}, fetch = FetchType.EAGER )
    @JoinColumn(name="parent_page")
    @Cascade(org.hibernate.annotations.CascadeType.ALL)
    private Pagina pagina;

    @OneToOne( cascade = {CascadeType.ALL}, fetch = FetchType.EAGER )
    @JoinColumn(name="parent_product")
    @Cascade(org.hibernate.annotations.CascadeType.ALL)
    private Produto produto;
}

在我的 Dao 类中,我尝试了两种方法来实现我的 persist(...) 方法:
@Transactional
public boolean persist(E transientInstance) {
    try {
        sessionFactory.getCurrentSession().persist(transientInstance);
        return true;
    } catch (RuntimeException e) {
        e.printStackTrace();
        return false;
    }
}

并且

@Transactional
public boolean persist(E transientInstance) {
    try {
        sessionFactory.getCurrentSession().save(transientInstance);
        return true;
    } catch (RuntimeException e) {
        e.printStackTrace();
        return false;
    }
}

使用这两个选项,如果我尝试保存一个没有“Pagina”或“Produto”属性的实体,它会被存储在数据库中而没有问题。但是如果我尝试提交带有这些属性的数据,就会遇到问题。
使用第一个选项,会触发异常“org.hibernate.PersistentObjectException: detached entity passed to persist”,而使用第二个选项,数据会被存储在数据库中,但会出现错误,因为一个具有空值的额外行被存储在数据库中,并且插入的数据行指向该行。
有人知道这里发生了什么吗?因为我一点头绪也没有。
PS:
我有个视图用于在那个表中插入数据:
<html lang="en">
  <head>
    <title>Pagina</title>
  </head>
  <body>
    <h1>Cadastro de Pagina</h1>


    <form id="command" role="form" class="form" action="Pagina/cadastra" method="post">

        <div class="panel panel-default">
            <div class="panel-heading">
            </div>
            <div class="panel-body">
                            <p>
                            <label for="nome" class="form-control">nome</label>
                            <input id="nome" name="nome" class="form-control" type="text" value=""/>
                            </p>

                            <p>
                            <label for="titulo" class="form-control">titulo</label>
                            <input id="titulo" name="titulo" class="form-control" type="text" value=""/>
                            </p>

                            <p>
                            <label for="descricao" class="form-control">descricao</label>
                            <textarea id="descricao" name="descricao" class="form-control"></textarea>
                            </p>

            </div>
        </div>

            <div class="panel panel-default">
                <div class="panel-heading">
                    Pagina
                </div>
                <div class="panel-body">

                        <input type="checkbox" name="Pagina.id" value="2">two<br>

                        <input type="checkbox" name="Pagina.id" value="1">one<br>

                </div>
            </div>

            <div class="panel panel-default">
                <div class="panel-heading">
                    Produto
                </div>
                <div class="panel-body">

                </div>
            </div>

        <p>
            <button type="submit" class="btn btn-lg btn-primary">Cadastrar</button>
        </p>

    </form>

    <div id="yes" class="alert alert-success" style="display: none;">
      <strong>Pronto!</strong> Solicita&ccedil;&atilde;o efetuada com sucesso.
    </div>

    <div id="not" class="alert alert-danger" style="display: none;">
      <strong>Erro!</strong> N&atilde;o foi possivel efetivar a sua solicita&ccedil;&atilde;o.
    </div>

  </body>
</html>

这个功能由以下方法处理:

在控制器类中

@RequestMapping(value="cadastra", method=RequestMethod.POST)
@ResponseBody
public String cadastra(@ModelAttribute("object") E object, BindingResult result) {
    if(serv.cadastra(object))
        return "yes";
    else
        return "not";
}

在服务类中
@PreAuthorize("hasPermission(#user, 'cadastra_'+#this.this.name)")
@Transactional
public boolean cadastra(E e) {
    return dao.persist(e);
}

更新

当我尝试插入实体时出现错误,以下是堆栈跟踪:

org.hibernate.PersistentObjectException: detached entity passed to persist: com.spring.loja.model.pagina.persistence.model.Pagina
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:139)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:801)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:794)
    at org.hibernate.engine.spi.CascadingActions$7.cascade(CascadingActions.java:314)
    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.cascade(Cascade.java:118)
    at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:432)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:265)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
    at com.spring.loja.config.generic.persistence.Dao.persist(Dao.java:33)
    at com.spring.loja.config.generic.persistence.Dao$$FastClassBySpringCGLIB$$ddbbe880.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:711)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)
    at com.spring.loja.model.pagina.persistence.PaginaHome$$EnhancerBySpringCGLIB$$7cc5cae5.persist(<generated>)
    at com.spring.loja.config.generic.service.service.cadastra(service.java:28)
    at com.spring.loja.config.generic.service.service$$FastClassBySpringCGLIB$$c92a3159.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:711)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:64)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)
    at com.spring.loja.model.pagina.service.PaginaService$$EnhancerBySpringCGLIB$$71a378e.cadastra(<generated>)
    at com.spring.loja.config.generic.controller.controller.cadastra(controller.java:69)
    at com.spring.loja.config.generic.controller.controller$$FastClassBySpringCGLIB$$c8cc444b.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:640)
    at com.spring.loja.model.pagina.controller.PaginaController$$EnhancerBySpringCGLIB$$8679f278_2.cadastra(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:838)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Jul 13, 2014 9:07:48 PM org.hibernate.AssertionFailure <init>
ERROR: HHH000099: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): org.hibernate.AssertionFailure: null id in com.spring.loja.model.pagina.persistence.model.Pagina entry (don't flush the Session after an exception occurs)
Jul 13, 2014 9:07:48 PM org.apache.catalina.core.StandardWrapperValve invoke
Grave: Servlet.service() for servlet [jsp_dispatcher] in context with path [/loja] threw exception [Request processing failed; nested exception is org.hibernate.AssertionFailure: null id in com.spring.loja.model.pagina.persistence.model.Pagina entry (don't flush the Session after an exception occurs)] with root cause
org.hibernate.AssertionFailure: null id in com.spring.loja.model.pagina.persistence.model.Pagina entry (don't flush the Session after an exception occurs)
    at org.hibernate.event.internal.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:77)
    at org.hibernate.event.internal.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:192)
    at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:152)
    at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:231)
    at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:102)
    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:555)
    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:478)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:272)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)
    at com.spring.loja.model.pagina.service.PaginaService$$EnhancerBySpringCGLIB$$71a378e.cadastra(<generated>)
    at com.spring.loja.config.generic.controller.controller.cadastra(controller.java:69)
    at com.spring.loja.config.generic.controller.controller$$FastClassBySpringCGLIB$$c8cc444b.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:640)
    at com.spring.loja.model.pagina.controller.PaginaController$$EnhancerBySpringCGLIB$$8679f278_2.cadastra(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:838)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

你能发布完整的堆栈跟踪吗? - geoand
在插入一個新的 Pagina 且 Pagina 或 Produits 的值不為空時,這兩個值是否存在於資料庫中? - Serge Ballesta
你的 PaginaProduto 类中存在一些问题,你在两个引用中都使用了 cascade = {CascadeType.ALL}。请提供完整的堆栈跟踪信息以获取此异常:org.hibernate.PersistentObjectException: detached entity passed to persist,这将给出实际引起异常的实体或属性。 - Ankur Singhal
@geoand和stacktrace发表了内容 - Kleber Mota
@SergeBallesta 是的,这些值存在于数据库中(我在视图中从复选框列表中选择它们,数据是从数据库检索的)。 - Kleber Mota
@ankur-singhal 发布了堆栈跟踪,异常来自实体Pagina(因为我选择了一个现有页面作为我要插入的新页面的属性)。 - Kleber Mota
1个回答

39

org.hibernate.PersistentObjectException: detached entity passed to persist

这个错误可以这样解释(哦,我该如何在不描述整个Hibernate/JPA对象生命周期的情况下做到这一点呢?):

使用JPA/Hibernate,您定义类为Entity。这意味着Hibernate可以管理此类的对象,并将其存储在数据库中。

但是,如果您尝试将一个已经“分离”的实体(即在Hibernate会话之外创建或获取的实体)传递给persist方法,就会引发PersistentObjectException异常。

@Entity
public class Entity { /** ... */ }

当你创建一个类的新对象,这个类是一个实体(new Entity()),Hibernate对它一无所知。它没有存储在数据库中,并且在任何方面都不受Hibernate的控制。如果我们希望发生这些事情,我们需要将对象持久化(em.persist(entity))。当我们这样做时,对象状态被存储在数据库中,但同时,对象本身也变成了由Hibernate管理,这意味着Hibernate将跟踪对象的状态。此外,如果你已经分配了Hibernate来生成id,那么对象将被分配一个id。
当你通过Hibernate从数据库加载一个对象时,这个对象也将被Hibernate管理。新持久化或加载的对象都将有一个id,并且都将由Hibernate管理。但是,对象和Hibernate之间的连接可能会断开!当这种情况发生时,对象就变成了detached。一个detached对象实际上只是一个entity类的对象,它的id已经设置好了,但是不再受Hibernate的管理。
当涉及到detached对象时,我们拥有的选项与管理对象或新对象时不同。与管理对象不同,不能将detached对象传递给persist方法,因为它们已经有了一个id,这意味着它们必须已经被持久化了!当想要将detached对象变成受管理的对象时,应该使用merge方法。(http://docs.oracle.com/javaee/7/api/javax/persistence/EntityManager.html#merge(T))这将把分离对象的状态与对象id对应的数据库状态合并。
使用没有id的新对象调用merge将为其分配一个id并保存它,但请注意它不会对作为参数传递的对象进行任何操作,而是返回受管理的对象。
public Entity saveDetached(final Entity entity) {
    return em.merge(entity);
} 

在您的情况下,解决方案将取决于一些因素,但如果所提到的Pagina始终是数据库中已存在的一个,我会从中删除persist操作的级联,并继续使用em.persist()merge有其弱点...)。如果它可能是新的,有时您还需要添加一些逻辑来确定是否要持久化它(在持久化拥有对象之前)。 (我也认为在persist之前从数据库加载PaginaProduto并将它们分配给新的Pagina可能有效。)
简而言之,当重新引入detached对象到持久性上下文中时,请使用EntityManagermerge方法,而不是persist方法。

好的,我尝试将级联操作从持久化操作中移除,现在,不再抛出PersistentObjectException异常,而是新行被正确插入,包括对所选页面的引用,但是这一行的数据被擦除了。你知道为什么会发生这种情况吗? - Kleber Mota
如果您没有开启persist级联,并且唯一的操作是对新的Pagina进行持久化,那么这种情况不应该发生。可能是其他问题导致的。请尝试调试并检查持久化前后的状态。 - Tobb
没关系,我只是在移除 cascade = {CascadeType.PERSIST},现在我还需要移除 @Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)。现在它运行得很好。 - Kleber Mota

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接