Вопрос по jpa-2.0, triggers – Триггеры против JPA Event

19

Я делаю веб-приложение, используя Spring 3.1.0.RELEASE, JSF 2.x, JPA 2 с провайдером Hibernate, MySql 5.1.x. Приложение работает на Tomcat 7.X.

В моих сущностях у меня есть некоторая дата, например, дата последнего обновления:

@Column(name = "last_update_date", insertable = false, updatable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date lastUpdateDate;

На данный момент у меня есть триггер, который обновляет:

CREATE TRIGGER upd_site BEFORE UPDATE ON site
FOR EACH ROW SET NEW.last_update_date = CURRENT_TIMESTAMP();

Это работает нормально, но я только заметил, что в JPA есть несколько методов обратного вызоваhttp://www.objectdb.com/java/jpa/persistence/event

Что является лучшим между JPA Events и триггерами MySql?

Благодарю.

Ваш Ответ

2   ответа
27

best вещь. Триггер базы данных будет обновлять дату последнего обновления при каждом обновлении строки, независимо от способа, используемого для обновления строки (Hibernate, запрос JDBC или обновление из вашего инструмента администратора базы данных). Обратный вызов JPA будет вызываться только при обновлении строки с использованием JPA. Вы можете хотеть одного или другого.

Другое отличие состоит в том, что JPA не знает о триггере, выполняемом базой данных. Поэтому, если вы обновите какое-либо поле в вашей сущности, и JPA сбросит изменение, дата обновления будет изменена триггером, но сущность JPA сохранит старое значение даты обновления в памяти. Таким образом, если эта дата обновления отображается в графическом интерфейсе после обновления, дата обновления будет неправильной. Вам нужно обновить сущность, чтобы получить самую последнюю дату обновления.

Комментарий во 2-м абзаце очень полезен.
Идеальный краткий набор различий между триггером базы данных и методом обратного вызова JPA. Работа cron также является хорошей альтернативой, если этого требует ваш вариант использования.
18

Я использовал оба способа с триггерами в БД и со слушателями JPA, я остановился на слушателях JPA, потому что:

the only code talking to the database in JPA code so I don't have to worry about the time stamp fields falling out of date. (If this changes in the future I can add triggers and change my mapped super calss)

JPA listeners are less complex in the sense that I did not have to go creating lots of triggers in my database so I had less things to maintain. Since I am actively developing and changing the db structure as I go along its great not to have to go and update triggers as I rapidly iterate through the development.

I have complete control over the database and made a rule for the db that every table was going to have a integer pkey, and an integer version, and that the time stamped tables would have insert_ts and update_ts columns these are universal rules in my db design so life is easy I have these two mapped superclases that make all my enitites simple to code since I extend from them.

@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;
    }

    @Override
    public String toString() {
        return "Presistable Object: pkey=" + this.pkey + " Object: " + this.getClass().getName();
    }
}

а также

@MappedSuperclass
public class TimeStampedPersistableObject extends PersistableObject {

    @Column(name = "insert_ts")
    @Temporal(TemporalType.TIMESTAMP)
    private Date    insertTimestamp;

    @Column(name = "update_ts")
    @Temporal(TemporalType.TIMESTAMP)
    private Date    updateTimestamp;

    @SuppressWarnings("unused")
    @PrePersist
    private void onInsert() {
        this.insertTimestamp = new Date();
        this.updateTimestamp = this.insertTimestamp;
    }

    @SuppressWarnings("unused")
    @PreUpdate
    private void onUpdate() {
        this.updateTimestamp = new Date();
    }


    public Date getInsertTimestamp() {
        return this.insertTimestamp;
    }


    public Date getUpdateTimestamp() {
        return this.updateTimestamp;
    }
}
Единственная проблема с событиями JPA заключается в том, что если вы хотите обновить базу данных с помощью SQL? Это обойдет события JPA. Как правило, база данных должна быть автономной, и поэтому администраторы баз данных скажут вам использовать триггеры. Разработчики предпочтут JPA события.

Похожие вопросы