我有3个实体 - Player,Hand和PlayerHandStats。前两个是常规表,ID是PK。 PlayerHandStats另一方面有一个复合PK(player_id,hand_id)。他们一起形成某种“包裹”,这就是为什么我试图坚持他们在一个街区。 ParsedHand只是一个捆绑实体的类 - 它包含1个手,2个10个玩家和2个10个PlayerHandStats。以下是我当前的幼稚方法,但实际上并不奏效。JPA批量插入如果不存在
public static void persist(ParsedHand parsedHand) {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(parsedHand.getHand());
Collection<Player> players = parsedHand.getPlayers().values();
for (Player player : players) {
em.persist(player);
}
Collection<PlayerHandStats> stats = parsedHand.getStats().values();
for (PlayerHandStats phs : stats) {
em.persist(stats);
}
em.getTransaction().commit();
em.close();
}
问题是,特定的播放器实体可能已经存在于数据库中 - 在这种情况下整个过程终止。我想保留它,不对实体执行任何合并或更新,但检索其'ID(因为在应用程序级没有分配ID)。
简单的例子(注意:列名和POKER_SITE形成一个唯一约束):
ID |NAME |POKER_SITE
----+------------+------------
0 |neverlimp92 |PokerStars
1 |player01 |PokerStars
现在,让我们说我有在应用水平领域的一个Player实体(NULL, 'neverlimp92','扑克之星)。显然,它将返回java.sql.SQLIntegrityConstraintViolationException,并且整个过程终止。我怎样才能避免这种情况?我应该重写的hashCode()和equals()方法,并进行
for (Player player : playes) {
if (!em.contains(player)) {
em.persist(player);
}
}
我不知道这是做一个聪明的做法,考虑有可能是潜在的10K的,甚至100K的行。
而且,如果实体确实存在,那么检索其ID并将其分配给应用级现有实例的正确方法是什么?
我对JPA很少有经验,任何形式的帮助,或者指引我朝着正确的方向非常感谢。谢谢。