问题描述
BundledProductData
是具有复合主键 BundledProductId
的实体。
@Data
@Entity
@Table(name = "bundled_product")
@IdClass(BundledProductId.class)
public class BundledProductData {
@CreationTimestamp
@Column(name = "created_date")
private Date createdDate;
@UpdateTimestamp
@Column(name = "updated_date")
private Date updatedDate;
@Id
@ManyToOne
@JoinColumn(name = "product_id",referencedColumnName = "productid")
private ProductData productData;
@Id
@ManyToOne
@JoinColumn(name = "product_bundle_id",referencedColumnName = "product_bundle_id")
private ProductBundleData productBundle;
}
BundledProductId
是复合 Id 类,其 ID 为 ProductData
和 ProductBundleData
。
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BundledProductId implements Serializable {
private ProductData productData;
private ProductBundleData productBundle;
}
尝试从级联更新 BundledProductData
条目时,我遇到了以下错误。
org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [io.apptizer.persistence.domain.BundledProductData#BundledProductId(productData=Product{productId='PRD_2kpe814p6f2',...)]
at org.hibernate.engine.internal.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:618) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:301) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:244) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:109) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:684) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:676) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.engine.spi.CascadingActions$5.cascade(CascadingActions.java:235) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascadetoOne(Cascade.java:350) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:379) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:319) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:296) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:167) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:158) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:91) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:55) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1258) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at io.dropwizard.hibernate.UnitOfWorkApplicationListener$UnitOfWorkEventListener.commitTransaction(UnitOfWorkApplicationListener.java:159) ~[dropwizard-hibernate-0.9.1.jar:0.9.1]
at io.dropwizard.hibernate.UnitOfWorkApplicationListener$UnitOfWorkEventListener.onEvent(UnitOfWorkApplicationListener.java:111) ~[dropwizard-hibernate-0.9.1.jar:0.9.1]
at org.glassfish.jersey.server.internal.monitoring.CompositeRequestEventListener.onEvent(CompositeRequestEventListener.java:71) ~[jersey-server-2.22.1.jar:na]
at org.glassfish.jersey.server.internal.process.RequestProcessingContext.triggerEvent(RequestProcessingContext.java:226) ~[jersey-server-2.22.1.jar:na]
at org.glassfish.jersey.server.ContainerFilteringStage$ResponseFilterStage.apply(ContainerFilteringStage.java:188) ~[jersey-server-2.22.1.jar:na]
at org.glassfish.jersey.server.ContainerFilteringStage$ResponseFilterStage.apply(ContainerFilteringStage.java:163) ~[jersey-server-2.22.1.jar:na]
at org.glassfish.jersey.process.internal.Stages.process(Stages.java:171) ~[jersey-common-2.22.1.jar:na]
at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:442) ~[jersey-server-2.22.1.jar:na]
at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:434) ~[jersey-server-2.22.1.jar:na]
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:329) ~[jersey-server-2.22.1.jar:na]
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) [jersey-common-2.22.1.jar:na]
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) [jersey-common-2.22.1.jar:na]
at org.glassfish.jersey.internal.Errors.process(Errors.java:315) [jersey-common-2.22.1.jar:na]
at org.glassfish.jersey.internal.Errors.process(Errors.java:297) [jersey-common-2.22.1.jar:na]
at org.glassfish.jersey.internal.Errors.process(Errors.java:267) [jersey-common-2.22.1.jar:na]
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) [jersey-common-2.22.1.jar:na]
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305) [jersey-server-2.22.1.jar:na]
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154) [jersey-server-2.22.1.jar:na]
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:471) [jersey-container-servlet-core-2.22.1.jar:na]
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:425) [jersey-container-servlet-core-2.22.1.jar:na]
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:383) [jersey-container-servlet-core-2.22.1.jar:na]
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:336) [jersey-container-servlet-core-2.22.1.jar:na]
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:223) [jersey-container-servlet-core-2.22.1.jar:na]
at io.dropwizard.jetty.NonblockingServletHolder.handle(NonblockingServletHolder.java:49) [dropwizard-jetty-0.9.1.jar:0.9.1]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669) [jetty-servlet-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.servlets.UserAgentFilter.doFilter(UserAgentFilter.java:83) [jetty-servlets-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.servlets.GzipFilter.doFilter(GzipFilter.java:300) [jetty-servlets-9.2.13.v20150730.jar:9.2.13.v20150730]
at io.dropwizard.jetty.BiDiGzipFilter.doFilter(BiDiGzipFilter.java:132) [dropwizard-jetty-0.9.1.jar:0.9.1]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) [jetty-servlet-9.2.13.v20150730.jar:9.2.13.v20150730]
at io.dropwizard.servlets.ThreadNameFilter.doFilter(ThreadNameFilter.java:29) [dropwizard-servlets-0.9.1.jar:0.9.1]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) [jetty-servlet-9.2.13.v20150730.jar:9.2.13.v20150730]
at io.dropwizard.jersey.filter.AllowedMethodsFilter.handle(AllowedMethodsFilter.java:43) [dropwizard-jersey-0.9.1.jar:0.9.1]
at io.dropwizard.jersey.filter.AllowedMethodsFilter.doFilter(AllowedMethodsFilter.java:38) [dropwizard-jersey-0.9.1.jar:0.9.1]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) [jetty-servlet-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585) [jetty-servlet-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515) [jetty-servlet-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at com.codahale.metrics.jetty9.InstrumentedHandler.handle(InstrumentedHandler.java:240) [metrics-jetty9-3.1.2.jar:3.1.2]
at io.dropwizard.jetty.RoutingHandler.handle(RoutingHandler.java:51) [dropwizard-jetty-0.9.1.jar:0.9.1]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.handler.RequestLogHandler.handle(RequestLogHandler.java:95) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:159) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.Server.handle(Server.java:499) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.httpconnection.onFillable(httpconnection.java:257) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540) [jetty-io-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) [jetty-util-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) [jetty-ut
如果我能知道我是否以错误的方式定义了复合键,那将是一个很大的帮助。这仅在发生更新时发生。创建新条目时一切正常。
解决方法
您已在引用具有 id X 的实体的属性上定义了合并级联,但具有 id X 的实体类型的不同对象已经与当前事务相关联。这就是您收到异常的原因。
这里有一个例子:
@Entity
class A {
@Id int id;
@ManyToOne(cascade = ALL) B b;
}
@Entity
class B {
@Id int id;
}
现在你加载了 ID 为 2 的 B,然后尝试将 A 与另一个 ID 为 2 的 B 持久化或合并。
B correctB = entityManager.find(B.class,2);
A a = new A(1,new B(2));
entityManager.merge(a);
要解决此问题,请使用 correctB
而不是创建新对象,或停用属性上的级联:
B correctB = entityManager.find(B.class,correctB);
entityManager.merge(a);