2010-12-10 1 views
2

다른 엔티티에 링크 된 엔티티 속성을 업데이트 할 때 eclipselink에서 배치 쓰기에 문제가 있습니다.JPA/Eclipselink ManyToOne 관계 변경시 성능이 좋지 않은 일괄 업데이트 엔티티

카드 엔티티와 @ManyToOne 관계가있는 카드 보유자가 있습니다.

@Entity 
@Table(name = "...") 
@NamedQueries({...}) 
public class Cardholder implements Serializable { 
    ... 
    @JoinColumn(name = "card_number", referencedColumnName = "...") 
    @ManyToOne(fetch=FetchType.LAZY) 
    private Card card; 
} 

및 카드 소지자

@Entity 
@Table(name = "cms_card") 
@NamedQueries({...}) 
public class Card implements Serializable { 
    @OneToMany(mappedBy = "card") 
    private List<Cardholder> cardholderList; 
} 

과 @OneToMany 관계를 가진 카드를 이미 아이의 목록 (카드 소지자를 지속)이있다. 이제 그 카드에 카드를 추가하고 싶습니다. // cardholderList는 관리 대상 엔티티 목록입니다.

for (Cardholder cardholder : cardholderList) { 
    Card newCard = new Card(); 
    ... 
    cardholder.setCard(newCard); 
    List<Cardholder> cardCardholders = new ArrayList<Cardholder>(); 
    cardCardholders.add(cardholder); 
    newCard.setCardholderList(cardCardholders); 
    cardsToBePersisted.add(newCard); 
    ++i; 
} 

나는 배치 쓰기를 사용하여 내 persistence.xml을 구성하지만, 성능은 + -15000 목록 업데이트에 대한 끔찍하게 느립니다.

FINER: Begin batch statements 
FINE: INSERT INTO cms_card (card_number, status, chip_serial_number, dwh_status, valid_until, card_holder_id, file_perso_history_id, feedback_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?) 
FINE:   bind => [9030002005890011, ACTIVE, null, false, 2015-12-10, null, 241, null] 
FINER: End Batch Statements 
FINER: Begin batch statements 
FINE: UPDATE cms_cardholder SET card_number = ? WHERE (id = ?) 
FINE:   bind => [9030002005890011, 176075] 
FINER: End Batch Statements 
FINER: Begin batch statements 
FINE: INSERT INTO cms_card (card_number, status, chip_serial_number, dwh_status, valid_until, card_holder_id, file_perso_history_id, feedback_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?) 
FINE:   bind => [9030002005889908, ACTIVE, null, false, 2015-12-10, null, 241, null] 
FINER: End Batch Statements 

나는 기존의 어린이들에게 새로운 부모 속성 (카드)를 설정하기 때문입니다 생각 : 내가 생성 된 SQL에 검사 할 때 지금, 나는 EclipseLink가이 같은 하나 개의 쿼리에 대해 하나 개의 배치를 만드는 것을 발견했다.

나는 또한 부모 - 자식 관계 (카드 -> 카드 소지자 대신 카드 소지자 -> 카드)를 뒤집어서 재생하려고합니다. 엔티티와 데이터베이스의 관계를 바꾼 후에도 일괄 삽입이 올바르지 만 Eclipselink는 cardholder.id =?와 같은 카드에서 SELECT *를 쿼리하므로 15000 레코드의 경우 15000 select 문을 갖게됩니다. 상기보다 좋지만 여전히 매우 느립니다.

일괄 쓰기 설정시 실수가 있습니까? 대단히 감사합니다.

+0

EntityManager 코드도 게시 할 수 있습니까? 언제든지 em.flush()를 발행하고 있습니까? –

답변

0

임 정말 문제의 원인에 대한 확인,하지만 난이 일을 제안하지 : 나는 oneToMany 및 manyToOne 상황을 가지고 있고, 그것을 수집 많은 데이터를 포함하는 경우

, 내가 컬렉션을 사용하지 않는 것 디테일을 추가하는 것이 필요하지 않을 때 콜렉션을 채울 수 있기 때문에 성능 문제의 원인이 될 수 있습니다.

내가 무엇을 의미하는지 설명하기 도움이 될 것입니다 간단한 예 : 팀 및 선수의 2 엔티티, 팀이 플레이어의 목록 (일대) 플레이어가 (한 많은) 팀을 가지고있다을 고려

새 플레이어를 추가하고 싶을 때마다 :

Team team = getTeamFromDbUsingEntityManager (teamId); 플레이어 플레이어 = 새 플레이어(); ... player.setTeam (team); entityManager.persist (player);

주목할만한 점은 team.addPlayer (player)입니다. 즉, 컬렉션을 만지는 것이 아닙니다.

1

카드 및 카드 소유자의 모든 관계는 무엇입니까?

두 클래스 사이에주기가있는 것 같으므로 EclipseLink는주기를 해결하기 위해 업데이트를 발행해야합니다.

카드에 card_holder_id가 있고 CardHolder에 card_number가 있습니까? 두 테이블 모두에 foriegn 키가있는 이유는 무엇입니까? 주기를 수정하면 인서트를 그룹화하고 최적의 배치를 허용 할 수 있습니다.

선택을 위해 무엇을하고 있는지 잘 모르십니까? 이것들은 새로운 물체입니까? 아니면 당신도 업데이트하고 있습니까?

관련 문제