2016-08-25 19 views
0

に私は休止状態4.3.11を使用して、別のエンティティにカスケード1対1の関係を持つエンティティを永続化しようとしたが、Hibernateが間違った順序で永続性をしようとしているように見えるのです私のOneToOneエンティティを永続化されますConstraintViolationExceptionが発生します。ここでHibernateは間違った順序

私の実体である:

@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レコード作成するべき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)を呼び出します。私はこのコードを実行すると は私が原因外部キーにDBでの整合性制約違反を打つ:明らかに

2016-08-24 15:03:00,425 DEBUG [org.hibernate.SQL] (http-nio-9090-exec-1) [SqlStatementLogger.java:109] insert into b2b_order_customer (customer_profile_txt, order_number) values (?, ?) 2016-08-24 15:03:00,606 WARN [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-nio-9090-exec-1) [SqlExceptionHelper.java:144] SQL Error: -530, SQLState: 23503 2016-08-24 15:03:00,607 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-nio-9090-exec-1) [SqlExceptionHelper.java:146] DB2 SQL Error: 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-nio-9090-exec-1) [AbstractBatchImpl.java:208] HHH000010: On release of batch it still contained JDBC statements 2016-08-24 15:03:00,721 ERROR [...] (http-nio-9090-exec-1) [OrderProcessor.java:188] Error persisting the order: org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:259) ~[spring-orm-4.2.3.RELEASE.jar!/:4.2.3.RELEASE] at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:225) ~[spring-orm-4.2.3.RELEASE.jar!/:4.2.3.RELEASE] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417) ~[spring-orm-4.2.3.RELEASE.jar!/:4.2.3.RELEASE] at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59) ~[spring-tx-4.2.3.RELEASE.jar!/:4.2.3.RELEASE] at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213) ~[spring-tx-4.2.3.RELEASE.jar!/:4.2.3.RELEASE] at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.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] at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:131) ~[spring-data-jpa-1.9.1.RELEASE.jar!/:na] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE] at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) [spring-aop-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] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) ~[spring-aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE] at com.sun.proxy.$Proxy111.save(Unknown Source) ~[na:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_91] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_91] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_91] at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_91] at 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] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) [spring-aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE] at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[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] at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85) [spring-aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE] ... at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_91] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_91] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_91] at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_91] at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621) [spring-aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE] at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610) [spring-aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE] at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:68) [spring-aop-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] at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) [spring-aop-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] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) ~[spring-aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE] at com.sun.proxy.$Proxy113.save(Unknown Source) ~[na:na] ... Caused by: com.ibm.db2.jcc.am.SqlIntegrityConstraintViolationException: DB2 SQL Error: 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.100.jar!/:na] at com.ibm.db2.jcc.am.fd.a(fd.java:60) ~[db2jcc4-4.15.100.jar!/:na] at com.ibm.db2.jcc.am.fd.a(fd.java:127) ~[db2jcc4-4.15.100.jar!/:na] at com.ibm.db2.jcc.am.qo.b(qo.java:2412) ~[db2jcc4-4.15.100.jar!/:na] at com.ibm.db2.jcc.am.qo.c(qo.java:2395) ~[db2jcc4-4.15.100.jar!/:na] at com.ibm.db2.jcc.t4.ab.l(ab.java:374) ~[db2jcc4-4.15.100.jar!/:na] at com.ibm.db2.jcc.t4.ab.a(ab.java:61) ~[db2jcc4-4.15.100.jar!/:na] at com.ibm.db2.jcc.t4.p.a(p.java:50) ~[db2jcc4-4.15.100.jar!/:na] at com.ibm.db2.jcc.t4.rb.b(rb.java:220) ~[db2jcc4-4.15.100.jar!/:na] at com.ibm.db2.jcc.am.ro.qc(ro.java:3526) ~[db2jcc4-4.15.100.jar!/:na] at com.ibm.db2.jcc.am.ro.b(ro.java:4489) ~[db2jcc4-4.15.100.jar!/:na] at com.ibm.db2.jcc.am.ro.ic(ro.java:807) ~[db2jcc4-4.15.100.jar!/:na] at com.ibm.db2.jcc.am.ro.executeUpdate(ro.java:781) ~[db2jcc4-4.15.100.jar!/:na] at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208) ~[hibernate-core-4.3.11.Final.jar!/:4.3.11.Final] ... 205 common frames omitted

Hibernateはご注文前にOrderCustomerを持続しようとしています。これは永続化されるべき反対の順序です。 OneToManyカスケード関係を考えると、単一のエンティティはコレクションの前に常に永続化されます(したがって外部キーが満たされます)。なぜこれは1対1では機能しませんか?

ありがとうございました。 JPA基準から

答えて

0

OrderCustomerが所有側である。この場合

For one-to-one bidirectional relationships, the owning side corresponds to the side that contains the corresponding foreign key

  • あなたはOrderCustomercascadeパラメータを移動し、OrderCustomer代わりのOrderを保存することができます。

  • あなたは Orderテーブルに @JoinColumnを移動することができます。

+0

これは私には意味がありません。OneToMany関係では、非所有(「1」側)から所有側(「多数」のコレクション)にカスケードすることができ、正常に動作します。なぜOneToOneでそれをすることができないのですか?また、JoinColumnを外部キーを持つ側に置くべきではありませんか?技術的にどちらかの側が所有者かもしれないが、私はそれを移すのが理にかなっているとは思わない。私たちのOneToManysがどのようにマッピングされているかと一貫しているようにしようとすると、これは反対のようです。 – user6757352

0

問題はoptionalパラメータです。どうして ?このパラメータがfalseの場合、Hibernateは「あなたを信頼して」、DBに関連するエンティティが含まれていると考えます。

両方のエンティティでoptional = falseを使用しています。これが問題です。

両方のエンティティがoptional = falseを持っている:だけ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_CUSTOMER (ORDER_NUMBER) values (?) 
ERROR :(Order table is empty. 

は:

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 :) 

のみ注文が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を見ることができます所有するSID e(OrderCustomer)のオーバーライドOrder@OneToOneoptionalパラメータ

関連する問題