J'ai un problème avec l'écriture par lots dans eclipselink lorsque je mets à jour une propriété d'entité qui lie à une autre entité.JPA/Eclipselink entité de mise à jour par lots de mauvaise performance sur les changements de relation ManyToOne
J'ai une entité de titulaire de carte avec une relation @ManyToOne avec l'entité de carte.
@Entity
@Table(name = "...")
@NamedQueries({...})
public class Cardholder implements Serializable {
...
@JoinColumn(name = "card_number", referencedColumnName = "...")
@ManyToOne(fetch=FetchType.LAZY)
private Card card;
}
et une carte avec relation @OneToMany avec titulaire
@Entity
@Table(name = "cms_card")
@NamedQueries({...})
public class Card implements Serializable {
@OneToMany(mappedBy = "card")
private List<Cardholder> cardholderList;
}
J'ai déjà Liste des enfants (persisté titulaires de carte). Maintenant, je veux ajouter une carte à eux, donc: // cardholderList est une liste d'entités gérées.
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;
}
J'ai configuré mon persistence.xml à utiliser l'écriture par lots, mais la performance est horriblement lent pour + -15000 mise à jour de la liste. Maintenant, quand je vérifie dans le SQL généré, je trouve que EclipseLink crée un lot pour une requête, son comme:
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
Je pense que cela est parce que je mets une nouvelle propriété parent (carte) aux enfants existants. J'essaie aussi de jouer avec l'inversion de la relation parent-enfant (titulaire de carte-> carte au lieu de carte-> titulaire de carte). L'insertion par lot est correcte après avoir inversé la relation dans l'entité et la base de données, mais Eclipselink interroge toujours la base de données (SELECT * de la carte où cardholder.id =?), Donc pour 15000 enregistrement j'ai l'instruction 15000 select. Mieux qu'au dessus, mais toujours très très lent.
Y a-t-il une erreur dans la configuration de l'écriture par lots? Merci beaucoup.
Pouvez-vous également publier le code EntityManager? Emettez-vous un em.flush() à tout moment? –