2016-07-18 4 views
1

저는 SO를 검색했지만 이에 대한 적절한 해결책을 찾지 못했습니다.스프링 JPA는 새로운 하위 엔티티의 부모 엔티티를 병합합니다.

@Entity 
public class Child { 
    @Id 
    @GeneratedValue 
    private int id; 

    @JoinColumn(name = "parentId") 
    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) 
    private Parent parent; 

}

내 시나리오는 조금 특별하다 : 부모 엔티티와 관련된 외부 키가

@Entity 
public class Parent { 
    @Id 
    @GeneratedValue 
    private int id; 

    @OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE) 
    private List<Child> childList; 
} 

그리고 자식 엔티티 : 나는 부모 엔티티를 말해봐. 자식 엔티티는 매 시간마다 엄청난 양으로 생성되며이를 데이터베이스에 저장해야합니다. 이러한 자식 개체에는 동일한 부모가있을 수 있으며 연결된 부모 엔터티는 이미 데이터베이스에있을 수 있습니다. 내 요구 사항은 entityManager에서 관리되는 상위 엔티티를 질의하지 않고 이러한 모든 하위 객체를 저장하는 것이고 상위 엔티티가 존재하는 경우 기존 엔티티를 병합/업데이트하기 만하면됩니다. 예 :

Child c = new Child(); 
// set some properties of child 
Parent p = new Parent(); 
// set some properties from my data into the parent. The parent may already exists 
child.setParent(p); 
JpaRepo.saveAndFlush(child);// If parent already exists, merge with the existed parent object, otherwise, create new parent object. 

분명히 작동하지 않습니다. 상위 엔티티가 존재하지 않으면 상위 엔티티를 올바르게 작성하고 연관시킵니다. 그러나 부모가 이미 존재하면 중복 키에 대한 예외가 발생하고 부모의 ID (병합을 통해 강제로 더미 값 사용)를 설정하면 분리 된 엔터티 객체의 예외가 발생합니다.

성능 제한으로 인해 부모 엔티티를 데이터베이스에서로드 할 수 없습니다. 너무 많아서 데이터베이스에서 상위 엔티티를로드 할 수 없습니다. 그렇다면 JPA 또는 데이터베이스가 기본 키를 위반할 때 자동으로 개체를 병합 할 수있는 방법이 있습니까?

MySQL을 사용하고 있습니다. 이중 키 업데이트를 사용할 수 있습니까?

+0

저장하기 전에 하위 개체에 부모 ID를 사용할 수 있습니까? –

+0

아니요, id가 없지만 개체를 ​​식별하는 고유 키로 사용할 수있는 모든 특성을 가지고 있습니다. – LynxZh

답변

0

조금 까다로운 직원이 되려고합니다. 당신이 당신의 추가 아이를 저장하기 위해 부모 개체가 존재하는지 확인하고 ChildSaveObject를 사용할 필요가이 흐름에

@Entity 
@Table(name = "sameAsTheOriginal") 
public class ChildSaveObject { 
    @Id 
    @GeneratedValue 
    private int id; //I think int will run out fast if there are a lot of objects but it is your choice. (Int max value: 2 147 483 647 is not that mutch) I prefer Long az id 

    @Column(name = "parentId") 
    private int parent; //note that You need to have the id of the parent object 

    //Other properties... 
} 

: 게으른 로딩 등 옵션은 (내가 좋아하는) 내가 다른 엔티티를 생성 당신에게 추천하지 않은 경우 그것에.

나는 대부분의 경우 많은 맵핑을 좋아하지 않지만, 그들은 단지 많은 문제의 뿌리라고 생각합니다. 그래도이 방법을 선호한다면 fetch = FetchType.LAZY을 사용하고 부모 엔티티를 가져와 (이렇게하면 필요없는 모든 하위 항목을로드하지 않게됩니다).

+0

부모로부터 자식을로드하지 않겠습니다. 새로운 자식을 만들고 존재하는 부모에 연결해야하거나, 존재하지 않으면 새 부모를 만드는 것이 중요합니다. – LynxZh

+0

이것은 부모가 존재하는지 확인하는 이유입니다. 쿼리를 실행하여 부모를 가져오고 존재하지 않는 쿼리를 작성하거나 최소화 된 쿼리를 설정합니다. – Mark

관련 문제