Обновление сущности Hibernate через EventListener - PullRequest
2 голосов
/ 18 февраля 2011

Я использую PreInsert и PreUpdate EventListeners в Hibernate, чтобы установить значение «созданных» и «обновленных» временных меток перед записью моей сущности в базу данных. Проблема заключается в следующем, когда Hibernate читает, а затем сбрасывает сущность. Hibernate видит измененные метки времени и считает, что объект необходимо обновить, даже если ничего не изменилось. Так что слушатели снова увольняются, происходит обновление, и то же самое снова и снова.

В идеале я хотел бы иметь возможность назначать эти временные метки без спящего режима, думая, что объект загрязнен при следующей очистке. Каково лучшее решение для обработки этого? Я полагаю, что могу отменить грязную проверку, но я хотел посмотреть, что делают другие.

Вот пример кода для справки (это просто пример кода, поэтому не нужно придираться):

@Entity
class MyEntity {
    @Id
    Long id = Long.valueOf(1);
    @Temporal(TemporalType.TIMESTAMP)
    private Date created;
    @Temporal(TemporalType.TIMESTAMP)
    private Date updated;

    @Override
    public void setCreated(Date created) {
        this.created = created;
    }

    @Override
    public void setUpdated(Date updated) {
        this.updated = updated;
    }
}

public class PreInsertAndUpdateEventListener implements PreInsertEventListener, PreUpdateEventListener {
    @Override
    public boolean onPreUpdate(PreUpdateEvent event) {
        MyEntity.class.cast(event.getEntity()).setUpdated(new Date());
        return false;
    }

    @Override
    public boolean onPreInsert(PreInsertEvent event) {
        MyEntity.class.cast(event.getEntity()).setCreated(new Date());
        return false;
    }
}

public void updatedTest() {
    Session session = sessionFactory.openSession();
    Transaction t = session.beginTransaction();

    MyEntity p = new MyEntity();
    Serializable id = session.save(p);
    session.flush();

    for (int i = 0; i < 5; i++) {
        p = (MyEntity) session.get(MyEntity.class, id);
        session.update(p);
        session.flush(); // Update always fires here
    }

    t.commit();
    session.close();
}

1 Ответ

0 голосов
/ 24 февраля 2011

Решение, которое я решил принять, состояло в том, чтобы обновлять состояние Hibernate, чтобы оно соответствовало состоянию объекта каждый раз, когда я изменяю объект с помощью прослушивателя событий. Реализация выглядит примерно так:

StandardProperty[] properties = event.getPersister().getEntityMetamodel().getProperties();
Object[] state = event.getState();

for (int i = 0; i < properties.length; i++) {
    if (properties[i].getName().equals("updated")) {
        state[i] = timestamp;
        break;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...