可以将多个产品保存在多个类别下。喜欢: 芒果可以用作水果类别和沙漠类别。
产品== [商品] 类别== [类型]
产品== [商品]
类别== [类型]
detached entity passed to persist: sari.core.domain.account.Genre; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist:
@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;
@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;
但是,没有运气。数小时陷入困境。任何帮助都将受到高度赞赏。
资源链接:
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中多对多连接的解决方案。
在JPA多对多关系中,如果已将层叠类型设置为CascadeType.PERSIST(或CascadeType.ALL,其中包括CascadeType.PERSIST),则在保存父级并使用子级的引用对其进行更新时,它将尝试再次保存该子级。
CascadeType.PERSIST
CascadeType.ALL
可能会出现以下问题:
子级已经在持久性存储中(A detached instance has been passed)-在这种情况下,它将引发异常“org.hibernate.PersistentObjectException: detached entity passed to persist”
(A detached instance has been passed)
“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,最好的选择是在尝试保存之前在服务器端查询实体。
cascade={CascadeType.MERGE,CascadeType.REFRESH}
在JPA中保留独立实体