Как использовать EntityManager из @PrePersist? - PullRequest
2 голосов
/ 11 марта 2011

У меня есть сущность / таблица "post" с этой "схемой":

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
int id;

@GeneratedValue(strategy = GenerationType.AUTO)
private Integer postId;

private Integer revisionId;
private Boolean isCurrentRevision;

Итак, таблица содержит сообщения, каждая из которых имеет несколько ревизий, но только одна (для каждого сообщения) является текущей.

Теперь, допустим, я хочу сохранить еще одну ревизию существующего поста (т.е. пост обновления):

Мне нужно найти максимальный существующий revisionId для этого postId, увеличить его и установить для revisionId. Кроме того, это новая текущая редакция, и поэтому она должна быть помечена соответствующим образом, но прежняя текущая редакция также должна быть помечена.

Но как я могу это сделать? Я чувствую, что это действительно должно быть частью реализации сущности, но с другой стороны, мне нужен EntityManager для этого. Но я не могу найти способ внедрить экземпляр EntityManager (который гарантированно существует).

Возможно ли это? Как вы реализуете такие сценарии? Спасибо!

Ответы [ 2 ]

5 голосов
/ 11 марта 2011

К сожалению, нет никакого чистого, портативного способа к тому, что вы предлагаете. Спецификация JPA 2 ( JSR 317 ) гласит следующее:

Как правило, метод жизненного цикла переносимого приложения не должен вызывать EntityManager. или Query операции, получить доступ к другим экземплярам сущности или изменить отношения внутри тот же постоянный контекст.

Что касается реализации, Hibernate запрещает это явно:

Метод обратного вызова не должен вызывать методы EntityManager или Query!

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

0 голосов
/ 11 марта 2011

Это может быть хорошим местом для шаблона переноса объекта.Обычно мы делаем это следующим образом:
1. преобразуем объект публикации в объект передачи сообщения
2. после сохранения сообщения мы выбираем самый высокий revisionId, увеличиваем его и создаем новый объект

В качестве альтернативы вы можете обновить текущую запись и добавить запись в таблицу истории (возможно даже в отдельной базе данных).Таким образом, вы можете сохранить таблицу постов как можно меньше для повышения производительности, так как в большинстве случаев текущая версия поста все равно будет требоваться.

...