title: Hibernate is persisting my OneToOne entities in the wrong order
body: <p>I am using Hibernate 4.3.11 and attempting to persist an entity with a one-to-one relationship cascading to another entity but Hibernate appears to be attempting the persistence in the wrong order which results in a ConstraintViolationException.</p>
  
  <p>Here are my entities:</p>
  
  <pre><code>@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;
  ...
  }
  </code></pre>
  
  <p>All I'm trying to do is create an Order with an OrderCustomer and persist the Order which should also create the OrderCustomer record:</p>
  
  <pre><code>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);
  </code></pre>
  
  <p>Note that orderRepository is a Spring repository object and all the save method does is call entityManager.persist(entity).
  When I run this code I hit an integrity constraint violation in the DB due to the foreign key:</p>
  
  <blockquote>
    <p>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</p>
  </blockquote>
  
  <p>Clearly Hibernate is trying to persist OrderCustomer before Order. This is the opposite order that it should be persisted. If you consider a OneToMany cascading relationship, the single entity would always be persisted before the collection (and thus the foreign keys are satisfied). Why does this not work for a one-to-one?</p>
  
  <p>Thanks.</p>