当我更新链接到其他实体的实体属性时,我在eclipselink中批量写入时遇到问题。
我有一个与卡片实体有@ManyToOne关系的持卡人实体。
@Entity
@Table(name = "...")
@NamedQueries({...})
public class Cardholder implements Serializable {
...
@JoinColumn(name = "card_number", referencedColumnName = "...")
@ManyToOne(fetch=FetchType.LAZY)
private Card card;
}
与持卡人的@OneToMany关系卡
@Entity
@Table(name = "cms_card")
@NamedQueries({...})
public class Card implements Serializable {
@OneToMany(mappedBy = "card")
private List<Cardholder> cardholderList;
}
我已经有了孩子名单(持卡人)。现在我想给他们添加一些卡片, 所以: // 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列表更新的性能非常慢。现在,当我检查生成的SQL时,我发现Eclipselink正在为一个查询创建一个批处理,如:
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
我认为这是因为我为现有的孩子设置了新的父母属性(卡片)。
我也试图改变父子关系(持卡人 - &gt;卡而不是卡 - &>持卡人)。 在我反转实体和数据库中的关系后批量插入是正确的,但是Eclipselink仍然会查询数据库(SELECT *来自card的cardholder.id =?),所以对于15000记录我得到15000选择语句。比上面好,但仍然非常慢。
我在设置批量写作时是否有任何错误? 非常感谢你。
答案 0 :(得分:1)
卡和持卡人的所有关系是什么?
您似乎在两个类之间有一个循环,因此EclipseLink必须发出更新以解决循环。
您的卡中有card_holder_id,CardHolder中有card_number吗?为什么两个表中都有一个foriegn键到另一个表?如果您修复了周期,则可以对插入进行分组并实现最佳批处理。
不确定你要做什么来获得选择?这些是他们注意到的新对象吗?或者你也在更新?
答案 1 :(得分:0)
我不确定您的问题的原因,但我建议这样做:
如果我有oneToMany和manyToOne情况,并且它涉及大量的收集数据,我将避免使用该集合来添加细节[s],因为它可能会触发在不需要时填充集合,这可能是性能问题的根源。
一个简单的例子,有助于说明我的意思: 考虑团队和玩家的2个实体, 一个团队有一个播放器列表(一对多) 玩家有一个团队(多对一)
每当我想添加一个新玩家时,我会这样做:
团队团队= getTeamFromDbUsingEntityManager(teamId); Player player = new Player(); ... player.setTeam(队); entityManager.persist(播放器);
请注意,它没有做team.addPlayer(播放器);这意味着,你并没有“触摸”这个系列。