2016-01-14 5 views
1

У меня есть требование установить значение date_updated в моей базе данных для каждой строки, когда эта строка обновляется. Назовем объект, с которым я работаю с Order, который имеет соответствующую таблицу orders в базе данных.Как выполнить именованные запросы из JPA EntityListener?

Я добавил колонку date_updated в таблицу orders. Все идет нормально.

@Entity Order объект, с которым я работаю, предоставляется третьей стороной. У меня нет возможности изменять исходный код, чтобы добавить поле под названием dateUpdated. У меня нет требования сопоставлять это значение с объектом в любом случае - это значение будет использоваться только для целей бизнес-аналитики и не должно быть представлено в объекте сущности Java.

Моя проблема заключается в следующем: я хочу обновить столбец date_updated в базе данных до текущего времени каждый раз, когда изменяется объект Order (и соответствующая строка таблицы базы данных).

Ограничения:

  • Мы используем Oracle, Spring, JPA и Hibernate
  • Я не могу использовать Oracle триггеры для обновления значения. Мы используем технологию репликации базы данных, которая не позволяет нам использовать триггеры.

Мой подход до сих пор было использовать JPA EntityListener, определенный в XML, похожее на это:

<entity-mappings xmlns="...."> 
    <entity class="com.theirs.OrderImpl"> 
    <entity-listeners> 
     <entity-listener class="com.mine.listener.OrderJPAListener" /> 
    </entity-listeners> 
    </entity> 
</entity-mappings> 

Мой класс слушатель выглядит следующим образом:

public class OrderJPAListener { 

    @PostPersist 
    @PostUpdate 
    public void recordDateUpdated(Order order) { 
    // do the update here 
    } 
} 

Проблема I У меня есть инъекция какой-либо поддержки настойчивости (или вообще чего-либо вообще) в моего слушателя. Поскольку JPA загружает слушателя с помощью своих методов, у меня нет доступа к каким-либо весенним бобам в моем классе слушателя.

Как мне ввести инъекцию EntityManager (или любой весенний боб) в мой класс слушателя, чтобы я мог выполнить именованный запрос для обновления поля date_updated?

ответ

1

Как я могу идти о нагнетании EntityManager (или любой компонента Spring) в моего класса слушателя, так что я могу выполнить именованный запрос для обновления date_updated поля?

Как указано выше, JPA 2.1 поддерживает ввод управляемых компонентов в приемник Entity через CDI. Независимо от того, поддерживает ли Spring это, я не уверен. В следующей статье предлагается специальное решение Spring.

https://guylabs.ch/2014/02/22/autowiring-pring-beans-in-hibernate-jpa-entity-listeners/

Возможный альтернативный подход, однако было бы переопределить SQL, генерируемый Hibernate на обновление, которое возможно как подробно описано ниже.

https://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/querysql.html#querysql-cud

Это было бы просто, если у вас был источник, вам просто нужно будет добавить @SQLUpdate аннотацию и тег на дополнительной колонке date_update.Как вы, однако, не вы должны смотреть на переопределение метаданные для этого объекта с помощью файла конфигурации XML и определение оператора SQL-обновления, как описано выше:

https://docs.jboss.org/hibernate/stable/annotations/reference/en/html/xml-overriding.html#xml-overriding-principles-entity

+0

Я закончил работу с чем-то похожим на решение guylabs.ch, используя функцию Spring для автоподготовки существующего экземпляра. Как оказалось, Spring достаточно умен, чтобы автоповолить поля, аннотированные с @PersistenceUnit. –

1

Поскольку JPA 2.1 Entity Слушатели CDI удалось. Вы пробовали использовать аннотацию @PersistenceUnit? Используете ли вы тип транзакции JTA?

В противном случае вы можете использовать Persistence.createEntityManagerFactory в классе Listener для извлечения контекста сохранения.

Смежные вопросы