分离实体传递给持久化

分离实体传递给持久化

本文介绍了JPA:分离实体传递给持久化:嵌套异常是 org.hibernate.PersistentObjectException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

多个产品可以保存在多个类别下.如:芒果可用作水果类别和沙漠类别.

Multiple product can be saved under multiple categories. Like: Mango can be used as Fruit category and Desert Category.

产品 == [商品]

类别 == [GENRE]

Category == [GENRE]

例外:

detached entity passed to persist: sari.core.domain.account.Genre; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist:

商品.java:

@Entity
@Table(name = "COMMODITY")
public class Commodity implements Serializable {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    .........
    .........
    @ManyToMany(fetch = FetchType.LAZY,
            cascade = {
                    CascadeType.MERGE,
                    CascadeType.PERSIST
                })
    @JoinTable(name = "commodity_genre", joinColumns = {
            @JoinColumn(name = "commodity_id", referencedColumnName = "id") }, inverseJoinColumns = {
                    @JoinColumn(name = "genre_id", referencedColumnName = "id") })
    @JsonManagedReference
    private List<Genre> genres;

流派.java:

@Entity
@Table(name = "GENRE")
public class Genre implements Serializable {

    private static final long serialVersionUID = 7643588406864492883L;

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    .........
    .........

    @ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE }, mappedBy = "genres")
    @JsonBackReference
    private List<Commodity> commodities;

我的行动计划:

  1. 检查您是否试图持久化具有相同 id 的实体作为另一个实体,并且已经存在于应用程序中的 PersistenceContext.
  2. 在保存或持久化之前不要设置 ID.休眠将看起来在您通过的实体处,它假定因为它有主键填充它已经在数据库中.各种各样的博客和个人,已经给出了使用删除 setId() 的解决方案

但是没有运气.卡住几个小时.任何形式的帮助都非常感谢.

But No luck. Getting stuck for hours. Any kind of help is highly appreciated.

资源链接:

Hibernate/JPA – 传递给持久化异常的分离实体

01-04-2018 00:55:39 [g.a.c.CommodityController:55] addCommodity : addCommodity() method started!!
01-04-2018 00:55:39 [g.a.c.CommodityController:56] addCommodity : Full Model: Commodity [id=null, commodityName=Pant, price=345.0, unit=3, genres=null]
01-04-2018 00:55:39 [g.a.c.CommodityController:57] addCommodity : Genre Name is: Cloth
01-04-2018 00:55:39 [g.a.c.CommodityController:58] addCommodity : commodityName is: Pant
01-04-2018 00:55:39 [g.a.d.i.CommodityDaoImpl:124] saveCommodities : saveCommodites called
01-04-2018 00:55:39 [g.a.d.i.CommodityDaoImpl:113] checkGenreExistsInDB : checkGenreExistsInDB started
Hibernate: select genre0_.id as id1_9_, genre0_.genre_name as genre_na2_9_ from genre genre0_ where genre0_.genre_name=?
01-04-2018 00:55:39 [g.a.d.i.CommodityDaoImpl:118] checkGenreExistsInDB : checkGenreExistsInDB ended
01-04-2018 00:55:39 [g.a.d.i.CommodityDaoImpl:133] saveCommodities : genre not Exists
01-04-2018 00:55:39 [g.a.d.i.CommodityDaoImpl:135] saveCommodities : genre save in DB started
Hibernate: insert into genre (genre_name) values (?)
Hibernate: insert into commodity (commodity_name, price, unit) values (?, ?, ?)
01-04-2018 00:55:39 [g.a.d.i.CommodityDaoImpl:137] saveCommodities : genre save in DB ended
01-04-2018 00:55:39 [g.a.d.i.CommodityDaoImpl:140] saveCommodities : Size of genreList: 1
Hibernate: insert into commodity (commodity_name, price, unit) values (?, ?, ?)
01-04-2018 00:55:39 [g.c.u.GlobalExceptionHandler:58] runtimeExceptionHandle : org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: sari.core.domain.account.Genre; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: sari.core.domain.account.Genre
        at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:299)
        at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:244)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:488)
        at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
        at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
        at com.sun.proxy.$Proxy160.save(Unknown Source)
        at sari.account.dao.impl.CommodityDaoImpl.saveCommodities(CommodityDaoImpl.java:142)
        at sari.account.services.CommodityService.saveCommodities(CommodityService.java:31)
        at sari.account.controllers.CommodityController.addCommodity(CommodityController.java:59)
        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:498)
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
        at sari.core.util.CorsConfiguration.doFilterInternal(CorsConfiguration.java:29)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:208)
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
        at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:798)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1434)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: sari.core.domain.account.Genre
        at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:124)
        at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:765)
        at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:758)
        at org.hibernate.jpa.event.internal.core.JpaPersistEventListener$1.cascade(JpaPersistEventListener.java:80)
        at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:398)
        at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
        at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:162)
        at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:431)
        at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:363)
        at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:326)
        at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:162)
        at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:111)
        at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:456)
        at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:278)
        at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:178)
        at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:109)
        at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:67)
        at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:189)
        at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:132)
        at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:58)
        at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:775)
        at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:748)
        at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:753)
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1146)
        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:498)
        at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298)
        at com.sun.proxy.$Proxy156.persist(Unknown Source)
        at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:508)
        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:498)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:504)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:489)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:461)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
        ... 76 more

01-04-2018 00:55:39 [g.c.u.GlobalExceptionHandler:77] <init> : Status: 200
01-04-2018 00:55:39 [g.c.u.GlobalExceptionHandler:78] <init> : Message : detached entity passed to persist: sari.core.domain.account.Genre; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: sari.core.domain.account.Genre
01-04-2018 00:55:39 [g.c.u.GlobalExceptionHandler:79] <init> : Trace: Resource Not Available

推荐答案

最后,我得到了 JPA 中多对多连接的解决方案.

At last, I got my solution for Many-to-Many connection in JPA.

在 JPA 多对多关系中,如果在 CascadeType.PERSIST(或 CascadeType.ALL,包括 CascadeType.PERSIST)中设置了级联类型,然后在保存父级并使用子级的引用更新它时,它会再次尝试保存子级.

In a JPA many-to-many relationship, if cascade type has been set at CascadeType.PERSIST (or CascadeType.ALL, which includes CascadeType.PERSIST), then while saving the parent and updating it with references of the child, it will try to save the child again.

可能会出现以下问题:

Child 已经在持久化存储中(一个分离的实例已经被传递) - 在这种情况下它会抛出一个异常org.hibernate.PersistentObjectException: detached entity传递给持久化"

Child is already in persistence store (A detached instance has been passed) -in this case it will throw an exception "org.hibernate.PersistentObjectException: detached entity passed to persist"

使用这个:

@ManyToMany(fetch = FetchType.EAGER,
        cascade = {
                CascadeType.MERGE,
                CascadeType.REFRESH
            })
@JoinTable(name = "commodity_genre", joinColumns = {
        @JoinColumn(name = "commodity_id", referencedColumnName = "id") }, inverseJoinColumns = {
                @JoinColumn(name = "genre_id", referencedColumnName = "id") })
@JsonManagedReference
private List<Genre> genres;

代替:

@ManyToMany(fetch = FetchType.LAZY,
        cascade = {
                CascadeType.MERGE,
                CascadeType.PERSIST
            })
@JoinTable(name = "commodity_genre", joinColumns = {
        @JoinColumn(name = "commodity_id", referencedColumnName = "id") }, inverseJoinColumns = {
                @JoinColumn(name = "genre_id", referencedColumnName = "id") })
@JsonManagedReference
private List<Genre> genres;

对于 JPA,最好的选择是在尝试保存实体之前在服务器端查询实体.

For JPA, the best option would be to query for entity on the server side before trying to save it.

  • 如果确定只会添加新的孩子,而不是分离的来自 DB 的实例,CascadeType.PERSIST 会处理它.
  • 另一方面,如果要求永远不会添加新孩子,如果它是尚未在 DB 中,则应删除 CascadeType.PERSISTcascade={CascadeType.MERGE,CascadeType.REFRESH} 应该使用
  • If its sure that only new child will be added, and not a detachedinstance from DB, CascadeType.PERSIST will take care of it.
  • On the other hand, if the requirement is never to add a new child if it'snot already in DB then CascadeType.PERSIST should be removed andcascade={CascadeType.MERGE,CascadeType.REFRESH} should be used

在 JPA 中保留分离的实体

这篇关于JPA:分离实体传递给持久化:嵌套异常是 org.hibernate.PersistentObjectException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 08:40