簡體   English   中英

Hibernate以錯誤的順序保留了我的OneToOne實體

[英]Hibernate is persisting my OneToOne entities in the wrong order

我正在使用Hibernate 4.3.11並嘗試保持具有一對一關系級聯到另一個實體的實體,但是Hibernate似乎試圖以錯誤的順序進行持久化,從而導致ConstraintViolationException。

這是我的實體:

@Entity
@Table(name = "B2B_ORDER")
public class Order implements java.io.Serializable
{

    @Id
    @Column(name = "ORDER_NUMBER", unique = true, nullable = false, length = 32)
    private String              orderNumber;

    @OneToOne(optional = false, cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "order")
    private OrderCustomer       orderCustomer;
...
}

@Entity
@Table(name = "B2B_ORDER_CUSTOMER")
public class OrderCustomer implements java.io.Serializable
{

    @Id
    @Column(name = "ORDER_NUMBER")
    private String            orderNumber;

    @OneToOne(optional = false)
    @JoinColumn(name = "ORDER_NUMBER", referencedColumnName =  "ORDER_NUMBER")
    private Order             order;
...
}

我要做的就是用OrderCustomer創建一個Order並保持Order,該Order還應該創建OrderCustomer記錄:

Order order = new Order();
order.setOrderNumber(orderNumber);
...
OrderCustomer orderCustomer = new OrderCustomer();
orderCustomer.setOrder(order);
orderCustomer.setOrderNumber(order.getOrderNumber());
order.setOrderCustomer(orderCustomer);
...
order = orderRepository.save(order);

請注意,orderRepository是一個Spring存儲庫對象,所有save方法所做的就是調用entityManager.persist(entity)。 當我運行此代碼時,由於外鍵,我在數據庫中遇到了完整性約束沖突:

2016-08-24 15:03:00,425 DEBUG [org.hibernate.SQL](http-nio-9090-exec-1)[SqlStatementLogger.java:109]插入b2b_order_customer(customer_profile_txt,order_number)值(?,?) 2016-08-24 15:03:00,606警告[org.hibernate.engine.jdbc.spi.SqlExceptionHelper](http-nio-9090-exec-1)[SqlExceptionHelper.java:144] SQL錯誤:-530,SQLState: 23503 2016-08-24 15:03:00,607錯誤[org.hibernate.engine.jdbc.spi.SqlExceptionHelper](http-nio-9090-exec-1)[SqlExceptionHelper.java:146] DB2 SQL錯誤:SQLCODE =- 530,SQLSTATE = 23503,SQLERRMC = CWSODEV2.B2B_ORDER_CUSTOMER.B2B_ORDER_CUSTOMER_ORD_NUM_FK,DRIVER = 4.15.100 2016-08-24 15:03:00,612 INFO [org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl](http- 9090-exec-1)[AbstractBatchImpl.java:208] HHH000010:在批量發布時,它仍包含JDBC語句2016-08-24 15:03:00,721錯誤[...](http-nio-9090-exec-1 )[OrderProcessor.java:188]保留訂單錯誤:org.springframework.dao.DataIntegrityViolationException:不能 t執行語句; SQL [n / a]; 約束[null]; 嵌套的異常是org.hibernate.exception.ConstraintViolationException:無法在org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:259)〜[spring-orm-4.2.3.RELEASE.jar!中執行語句/:4.2.3.RELEASE],位於org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:225)〜[spring-orm-4.2.3.RELEASE.jar!/:4.2.3.RELEASE ]在org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417)〜[spring-orm-4.2.3.RELEASE.jar!/:4.2.3.RELEASE]在org.springframework.dao.support .org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)〜[spring-tx-4.2.3.RELEASE.jar!/:4.2.3.RELEASE] 213)〜[spring-tx-4.2.3.RELEASE.jar!/:4.2.3.RELEASE]在org.springframework.dao.support.Persi stenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)〜[spring-tx-4.2.3.RELEASE.jar!/:4.2.3.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179 )[spring-aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE]在org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor $ CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:131)〜[spring -data-jpa-1.9.1.RELEASE.jar!/:na],位於org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)[spring-aop-4.2.3.RELEASE.jar!/ :4.2.3.RELEASE],位於組織org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)[spring-aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE]。在org.sp上的springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)[spring-aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE] ringframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)〜[spring-aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE] at com.sun.proxy。$ Proxy111.save(未知來源)〜[na:na]位於sun.reflect.NativeMethodAccessorImpl.invoke0(本地方法)〜[na:1.8.0_91]位於sun.reflect.NativeMethodAccessorImpl.invoke(未知來源)〜[na:1.8.0_91]位於sun.reflect.DelegatingMethodAccessorImpl.invoke(未知來源)〜[na:1.8.0_91],位於java.lang.reflect.Method.invoke(未知來源)〜[na:1.8.0_91],位於org.springframework.aop.support。 AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)〜[spring-aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190 )[spring-aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE]位於org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)[spring-aop-4.2.3。 RELEASE.jar!/:4.2.3.RELEASE],位於org.springframework.dao.support.Persistence ExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)〜[spring-tx-4.2.3.RELEASE.jar!/:4.2.3.RELEASE]在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) )[spring-aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE]在org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)[spring-aop-4.2.3。 RELEASE.jar!/:4.2.3.RELEASE] ...在sun.reflect.NativeMethodAccessorImpl.invoke0(本機方法)〜[na:1.8.0_91]在sun.reflect.NativeMethodAccessorImpl.invoke(未知源)〜[na :1.8.0_91],位於java.lang.reflect.Method.invoke(未知源)〜[na:1.8.0_91],位於sun.reflect.DelegatingMethodAccessorImpl.invoke(未知源)〜[na:1.8.0_91]。 springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)[spring-aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE]在org.springframework.aop.aspectj.AbstractAspectJAdvice.i nvokeAdviceMethod(AbstractAspectJAdvice.java:610)[spring-aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE]在org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:68)[spring -aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE],位於org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)[spring-aop-4.2.3.RELEASE.jar !/:4.2.3.RELEASE]在org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)[spring-aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE] org.springframework.aop.framework.JdkDynamicAopProxy上的org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)[spring-aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE]。 invoke(JdkDynamicAopProxy.java:208)〜[spring-aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE]在com.sun.proxy。$ Proxy113.save(未知來源)〜[na:na ] ...由以下原因引起:com.ibm.db2.jcc.am.SqlIntegrityConstraintViolationException:DB2 SQL錯誤:SQLCODE = -530,SQLSTATE = 23503,SQLERRMC = CWSODEV2.B2B_ORDER_CUSTOMER.B2B_ORDER_CUSTOMER_ORD_NUM_FK,DRIVER = 4.15.100 at com.ibm.db2.jcc.am.fd.a(fd.java:692)〜[db2jcc4-4.15。 com.ibm.db2.jcc.am.fd.a上的jar!/:na](fd.java:60)com.ibm.db2.jcc上的[db2jcc4-4.15.100.jar!/:na]。 am.fd.a(fd.java:127)〜[db2jcc4-4.15.100.jar!/:na]在com.ibm.db2.jcc.am.qo.b(qo.java:2412)〜[db2jcc4 -4.15.100.jar!/:na]在com.ibm.db2.jcc.am.qo.c(qo.java:2395)〜[db2jcc4-4.15.100.jar!/:na]在com.ibm .db2.jcc.t4.ab.l(ab.java:374)〜[db2jcc4-4.15.100.jar!/:na]在com.ibm.db2.jcc.t4.ab.a(ab.java: 61)在com.ibm.db2.jcc.t4.pa(p.java:50)處[db2jcc4-4.15.100.jar!/:na]在[.db2jcc4-4.15.100.jar!/:na] com.ibm.db2.jcc.am.ro.qc(ro上的com.ibm.db2.jcc.t4.rb.b(rb.java:220)〜[db2jcc4-4.15.100.jar!/:na] .java:3526)〜[db2jcc4-4.15.100.jar!/:na]在com.ibm.db2.jcc.am.ro.b(ro.java:4489)〜[db2jcc4-4.15.100.jar! /:na]位於com.ibm.db2.jcc.am.ro.ic(ro.java:807)〜[db2jcc4-4.15.100.jar!/:na]位於com.ibm.db2.jcc.am。 ro.executeUpdate(ro.java:781)〜[db2jcc4-4.1 5.100.jar!/:na]在org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208)〜[hibernate-core-4.3.11.Final.jar!/:4.3.11.Final ] ...省略205個通用框架

顯然,Hibernate嘗試在Order之前保留OrderCustomer。 這是應該堅持的相反順序。 如果考慮一個OneToMany級聯關系,則單個實體將始終在集合之前保留下來(因此將滿足外鍵)。 為什么這對一對一不起作用?

謝謝。

從JPA參考:

對於一對一的雙向關系,擁有方對應於包含相應外鍵的方

在這種情況下, OrderCustomer是擁有方。

  • 您可以將cascade參數移至OrderCustomer並保存OrderCustomer而不是Order

  • 您可以將@JoinColumn移到Order表。

問題是optional參數。 為什么呢 如果此參數為false ,則Hibernate“信任您”並認為數據庫包含相關實體。

您在兩個實體中都使用optional = false 這就是問題。

當兩個實體都具有optional = false

Hibernate: create table B2B_ORDER (ORDER_NUMBER varchar(32) not null, primary key (ORDER_NUMBER))
Hibernate: create table B2B_ORDER_CUSTOMER (ORDER_NUMBER varchar(32) not null, primary key (ORDER_NUMBER))
Hibernate: alter table B2B_ORDER_CUSTOMER add constraint FKsvt9d7j362lni8mxb83y7cygj foreign key (ORDER_NUMBER) references B2B_ORDER
Hibernate: insert into B2B_ORDER_CUSTOMER (ORDER_NUMBER) values (?)
ERROR :( Order table is empty.

當只有OrderCustomer具有optional = false

Hibernate: create table B2B_ORDER (ORDER_NUMBER varchar(32) not null, primary key (ORDER_NUMBER))
Hibernate: create table B2B_ORDER_CUSTOMER (ORDER_NUMBER varchar(32) not null, primary key (ORDER_NUMBER))
Hibernate: alter table B2B_ORDER_CUSTOMER add constraint FKsvt9d7j362lni8mxb83y7cygj foreign key (ORDER_NUMBER) references B2B_ORDER
Hibernate: insert into B2B_ORDER (ORDER_NUMBER) values (?)
Hibernate: insert into B2B_ORDER_CUSTOMER (ORDER_NUMBER) values (?)
SUCCESS :)

當只有Order具有optional = false

Hibernate: create table B2B_ORDER (ORDER_NUMBER varchar(32) not null, primary key (ORDER_NUMBER))
Hibernate: create table B2B_ORDER_CUSTOMER (ORDER_NUMBER varchar(255) not null, primary key (ORDER_NUMBER))
Hibernate: insert into B2B_ORDER_CUSTOMER (ORDER_NUMBER) values (?)
Hibernate: insert into B2B_ORDER (ORDER_NUMBER) values (?)
SUCCESS :)

你可以看到, @OneToOne上擁有方( OrderCustomer )重寫Order @OneToOne optional參數

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM