Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » JPA/Eclipselink poor performance batch update entity on ManyToOne relationship changes(JPA Batch-Writing)
JPA/Eclipselink poor performance batch update entity on ManyToOne relationship changes [message #644316] Fri, 10 December 2010 14:06 Go to next message
Andoko  is currently offline Andoko
Messages: 4
Registered: December 2010
Junior Member
I have problem with batch writing in eclipselink when i update an entity properties which link to other entity.

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


and a Card with @OneToMany relationship with cardholder

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


I already have List of child (persisted cardholders). Now i want to add some card to them, so : // cardholderList is a managed entity list.

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;
}


I configured my Persistence.xml to use batch-writing, but performance is horribly slow for +-15000 list update. Now, when i check into generated SQL, i found that Eclipselink is creating one batch for one query, its like :

FINER: Begin batch statements
FINE: INSERT IGNORE 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 IGNORE 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


I think this is because i set a new parent property (card) to existing children.

I also try to play with reversing the parent - child relationship (cardholder->card instead of card->cardholder). Batch insert is correct after i reverse the relationship in entity and database, but still Eclipselink would query the database (SELECT * from card where cardholder.id = ?), so for 15000 record i got 15000 select statement. Better than above, but still very very slow.

Is there any mistake i made in setting up batch-writing? Thank you very much.
Re: JPA/Eclipselink poor performance batch update entity on ManyToOne relationship changes [message #644375 is a reply to message #644316] Fri, 10 December 2010 18:02 Go to previous messageGo to next message
Chris Delahunt is currently offline Chris Delahunt
Messages: 1034
Registered: July 2009
Senior Member
Hello,

I can't tell as it may have just been excluded from the information provided, but how is the newCard becoming managed in the EntityManager context?
Additional info that will help are how and when you are writing out the changes, and what version is being used. you get the same problem on the latest EclipseLink nightly build if you are on an older version?

Its hard to tell without the full log on set to log everything, but my guess is that this is occuring because the commit order is processing the Cardholder objects first. For each it encounters, it discovers a new Card that must be inserted before the update can occur. If that is the case, the descriptor processing can be ordered so that Card inserts are processed first. This can be changed by setting constraint dependencies on the ClassDescriptor (via a customizer) - this should already be done because of the ManyToOne mapping, but means that your model probably has a circular reference involved that requires the CardHolders to be inserted first.

Best Regards,
Chris
Re: JPA/Eclipselink poor performance batch update entity on ManyToOne relationship changes [message #644425 is a reply to message #644375] Sat, 11 December 2010 05:00 Go to previous message
Andoko  is currently offline Andoko
Messages: 4
Registered: December 2010
Junior Member
Hi Christ,

i call em.persist(Card) for every card in there before the transaction end (in an CMT SLSB).

Yes, after i re-check, it seems that card and cardholder has circular reference. (card has ManyToOne relationship with cardholder, and vice versa). I think this is a design mistake, but lets suppose i can not change the DB design, is there something i could do to tell Eclipselink to process the Cards insert firs?

Best regards,
Andoko
Previous Topic:TableGenerator Sequencing options
Next Topic:LoadTimeWeaving stopped working when upgrading to Maven 3
Goto Forum:
  


Current Time: Thu Oct 23 07:56:42 GMT 2014

Powered by FUDForum. Page generated in 0.01975 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software