2013-03-03 4 views
3

У меня есть 3 объекта - игрок, рука и плеерHandStats. Первые две являются регулярными таблицами с идентификатором как ПК. PlayerHandStats, с другой стороны, имеет составную PK (player_id, hand_id). Вместе они образуют какой-то «пакет», поэтому я стараюсь упорствовать в одном блоке. ParsedHand - это просто класс, который связывает сущности - он содержит 1 Hand, 2..10 Player и 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(); 
} 

Проблема заключается в том, что конкретный объект Player может уже существовать в БД - в этом случае весь процесс завершается. Я хотел бы сохранить это, не выполнять слияние или обновление для объекта, а получить его идентификатор (поскольку на уровне приложения он не имеет идентификатора).

Быстрый пример (Примечание: столбцы NAME и POKER_SITE образуют UNIQUE CONSTRAINT):

ID |NAME  |POKER_SITE 
----+------------+------------ 
0 |neverlimp92 |PokerStars 
1 |player01 |PokerStars 

Теперь, скажем, у меня есть сущность игрока на прикладном уровне с полями (нуль, 'neverlimp92', ' PokerStars'). Очевидно, он вернет java.sql.SQLIntegrityConstraintViolationException, и весь процесс завершается. Как я могу избежать этого? Должен ли я переопределить хэш-код() и Equals() методы, а также выполнять

for (Player player : playes) { 
    if (!em.contains(player)) { 
     em.persist(player); 
    } 
} 

Я не уверен, если это умная вещь, чтобы сделать, учитывая, могут быть потенциально 10k, даже 100K в ряды.

А также, если сущность существует, каков правильный способ получить свой идентификатор и присвоить его существующему экземпляру на уровне приложения?

У меня очень мало опыта работы с JPA, и любая помощь или указание меня в правильном направлении очень ценится. Спасибо.

ответ

0

Если игроки могут быть существующими игроками, то для каждого игрока вам необходимо запросить базу данных для игрока с этим именем и сайтом, если он существует, если он не сохранился.

Это зависит от того, насколько вероятно, что это такой игрок. Если это очень маловероятно, вы можете просто сохранить его, и если коммит не удастся, повторите попытку со вторым алгоритмом.

В общем, было бы лучше, если бы у вашего игрока был свой идентификатор, тогда вы знали бы, что он новый или существующий.

Смежные вопросы