Я создаю новое веб-приложение и использую Spring, JPA / Hibernate и Postgres. В некоторых из моих таблиц есть столбцы creation_ts и lastupdate_ts, которые представляют собой столбцы отметок времени, которые отслеживают, когда произошла вставка и когда произошло последнее обновление в строке.
Я также использую соглашение об именах для столбцов в моих таблицах, так что в соответствии с политикой проектирования каждая таблица гарантированно имеет два столбца pkey, который является целочисленным суррогатным ключом, и версию для оптимистической блокировки.
У меня есть два способа поддерживать эти поля в актуальном состоянии.
Вариант A: использовать триггеры
Это решение, которое у меня есть на данный момент, у меня есть два триггера Postgres, которые запускаются при вставке и обновлении и будут обновлять эти поля. и у меня есть два класса.
@MappedSuperclass
public abstract class PersistableObject
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="pkey")
private Integer pkey;
@Version
@Column(name="version")
private Integer version;
public Integer getPkey()
{
return this.pkey;
}
public Integer getVersion()
{
return this.version;
}
}
а у меня
@MappedSuperclass
public class TimeStampedPersistableObject extends PersistableObject {
@Column(name = "creation_ts")
@Temporal(TemporalType.DATE)
@org.hibernate.annotations.Generated(value = GenerationTime.INSERT)
private Date creationTimestamp;
@Column(name = "update_ts")
@Temporal(TemporalType.DATE)
@org.hibernate.annotations.Generated(value = GenerationTime.ALWAYS)
private Date updateTimestamp;
public Date getCreationTimestamp()
{
return this.creationTimestamp;
}
public Date getUpdateTimestamp()
{
return this.updateTimestamp;
}
}
Вариант B: использовать JPA-слушатели
В этом варианте я бы использовал обработчики JPA, чтобы поддерживать актуальность столбцов меток времени.
Мой вопрос:
Какой из этих двух подходов лучше? Как я вижу, здесь есть мой личный список плюсов и минусов каждого варианта, и мне очень интересно услышать опыт других с этими двумя вариантами.
Вариант А плюсы:
- База данных выполняет обновления с помощью триггеров, поэтому нет опасности, что на кластере, работающем в веб-приложении, будет асимметрия часов.
- Если приложение не из JPA обращается к базе данных, требование соблюдения этих двух столбцов выполняется.
Вариант A минусы:
- Необходимо сделать выбор после вставки и обновления, чтобы прочитать значения, которые триггеры установили на место.
- Я использую аннотации в спящем режиме для считывания значений
Варианты B, плюсы:
- Меньше ввода при создании DDL
- Нет необходимости считывать значения из базы данных после вставки и обновления
- Чистые аннотации JPA без специальных спящих аннотаций
Варианты B минусы:
- Опасность перекоса часов в кластере
- Поля, установленные всякий раз, когда поставщик JPA решает вызвать методы обратного вызова, не предсказуемые
Как вы решите эту проблему для нового приложения, где у вас есть полный контроль над базой данных и кодом Java.