2017-12-12 3 views
0

hibernate.order_inserts 때문에 이상한 문제가 있습니다. 다음예기치 않은 순서로 hibernate.order_inserts가 작동하는 방식

@Entity 
@Table 
@Access(AccessType.FIELD) 
public class Employee { 

    @Column 
    private String name; 

    @Id 
    @SequenceGenerator(name = "EMP_SEQ", sequenceName = "EMP_SEQ", allocationSize = 50) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "EMP_SEQ") 
    @Column 
    private Long id; 

    @Column 
    private String salary; 

    @Fetch(FetchMode.SELECT) 
    @OneToMany(mappedBy = "employee", cascade = CascadeType.ALL) 
    private List<Address> address; 
} 


@Entity 
@Access(AccessType.FIELD) 
public class Address implements Serializable { 

    @Column 
    private String street; 

    @Id 
    @SequenceGenerator(name = "ADD_SEQ", sequenceName = "ADD_SEQ", allocationSize = 50) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ADD_SEQ") 
    @Column(name = "ADDRESSID") 
    private Long addreessId; 

    @Fetch(FetchMode.SELECT) 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "EMPID") 
    private Employee employee; 

} 

http://docs.jboss.org/hibernate/orm/3.5/javadocs/org/hibernate/event/def/AbstractFlushingEventListener.html#performExecutions%28org.hibernate.event.EventSource%29 삽입이 executed.Lets는 예를 들어 말씀이 있습니다 방법을 주문합니다

<bean id="entityManagerFactory" name="emp" 
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="persistenceUnitName" value="emp" /> 
    <property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml" /> 
    <property name="jpaProperties"> 
     <props> 
      <prop key="hibernate.show_sql">true</prop> 
      <prop key="hibernate.format_sql">true</prop> 
      <prop key="hibernate.order_updates">true</prop> 
      <prop key="hibernate.order_inserts">true</prop> 
      <prop key="hibernate.jdbc.batch_versioned_data">true</prop> 
      <prop key="hibernate.jdbc.batch_size">30</prop> 
      <prop key="org.hibernate.flushmode">COMMIT</prop> 
      <prop key="hibernate.id.new_generator_mappings">false</prop> 
     </props> 
    </property> 
</bean> 
이제

문서를 최대 절전 모드로 따라 내 entitymanager 구성입니다 아래의 예를 고려

public static void main(String[] args) { 
     ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/META-INF/spring/batch-context.xml"); 
     EntityManagerFactory entityManagerFactory = (EntityManagerFactory) applicationContext.getBean("entityManagerFactory"); 
     EntityManager entityManager = entityManagerFactory.createEntityManager(); 

     Employee kumar = entityManager.getReference(Employee.class, 2l); 

     Address kumarAddress = new Address(); 
     kumarAddress.setStreet("kiev"); 
     kumarAddress.setEmployee(kumar); 

     Employee pavan = new Employee(); 
     pavan.setName("xyz"); 
     pavan.setSalary("100000"); 

     Address pavanAddress = new Address(); 
     pavanAddress.setStreet("USA"); 
     pavanAddress.setEmployee(pavan); 

     List<Address> emp2Address = new ArrayList<Address>(); 
     emp2Address.add(pavanAddress); 

     pavan.setAddress(emp2Address); 

     entityManager.getTransaction().begin(); 

     entityManager.persist(kumarAddress); 

     entityManager.persist(pavan); 

     entityManager.getTransaction().commit(); 

     entityManager.close(); 

    } 

kumarAddress 삽입이 먼저 실행되기 때문에 d가 hibernate.order_inserts을 활성화했기 때문에 최대 절전 모드는 두 주소를 함께 삽입해야합니다. 따라서 pavanAddress은 아직 삽입되지 않은 pavan에 의존하므로 실패해야합니다.

이 경우 최대 절전 모드로 쿼리를 삽입하는 방법 위의 코드는 잘 작동하지만 내 프로젝트의이 문제에 직면하고 있습니다 .Hibernate는 자식 부모가 삽입되지 않은 경우에도 두 자식 삽입을 함께 일괄 처리합니다. hibernate.order_inserts을 비활성화하십시오. 이 경우 최대 절전 모드 작동 방식을 이해하려고합니다.

답변

0

Hibernate는 여러분의 자식 엔티티가 아빠에 의존하고 이전에 삽입 할 것임을 알 수 있습니다. 의 당신이 부모와 순서이 최대 절전 모드처럼

A1 
B1 
A2 
B2 

문이 다른 대상 제대로 때문에 할 수없는 일괄 2 차일을 유지하고 싶은 말은하자 : 일괄 삽입 할 때

삽입 주문에 대한 속성은 활동하기 시작 표. order_inserts와

문이 제대로 테이블에 의해 명령을 받게됩니다 (가능한 경우) 은 그래서 당신은 불행하게도 내 application.It에서 일어나는되지

A1 
A2 
B1 
B2 
+0

을 얻을려고하는 자식 테이블과 배치 그들에게 – pppavan

+0

에 삽입 트리거 간단합니다 : 당신은 B1, A1, B2를하고 있습니다. Hibernate는 B1이 A1을 먼저 필요로하므로 FK 실패 (A1, B1, B2)를 피하기 위해 순서대로 알릴 것이다. – Zeromus