Как объект получает идентификатор до совершения транзакции в JPA/Play?
См. этот вопрос.
Оказывается, что даже без совершения транзакции вручную, перед передачей TX, у человека есть идентификатор после вызова метода save().
Разве база данных не отвечает за определение поля ID? Если да, как можно заполнить поле ID перед фиксацией? Происходит ли какое-либо сообщение с БД до передачи TX?
Ответы
Ответ 1
Да, JPA разрешено связываться с БД до совершения транзакции. Это может произойти, например, когда вы явно вызываете EntityManager#flush()
.
Кроме того, провайдеру JPA разрешено выполнять флеш-операцию всякий раз, когда он считает это необходимым. Однако, по удобству, поставщики JPA задерживают операции БД до момента совершения транзакции.
Некоторые стратегии автоматического генератора идентификаторов должны попасть в базу данных, чтобы получить значение PK (насколько я помню, стратегия IDENTITY
работает таким образом).
Как обратное, генераторам TABLE
или SEQUENCE
нет необходимости в попадании в БД для получения значения ID. Они используют параметр allocationSize
, чтобы спросить DB TABLE или SEQUENCE для пакетных идентификаторов, которые будут переданы новым сущностям без дальнейшей связи с базой данных.
Ответ 2
Играть! (который записывает изменения в базу данных и позволяет получить сгенерированный идентификатор) каждый раз, когда вы сохраняете объект, используя метод save() для модели:
Из исходного кода JPABase._save():
if (!em().contains(this)) {
em().persist(this);
PlayPlugin.postEvent("JPASupport.objectPersisted", this);
}
// ...
try {
em().flush();
} catch (PersistenceException e) {
// ...
}
Ответ 3
как я знаю, мы не сможем получить идентификатор объекта (предположим, что он пронумерован автоматически) до его сохранения.
и я лично считаю, что довольно опасно назначать что-то, что должно быть сделано СУРБД вне его.
Ответ 4
Взаимодействие между инициалами и фиксацией, после вызова метода сохранения или обновления, вы должны использовать:
EntityManagerHelper.getEntityManager().flush();
Если вы его не назовете, объект будет потерян и не может быть сохранен в БД.
Итак, после его вызова вы будете использовать id объекта в объекте.