Как внедрить служебный бин источника в объект JPA? - PullRequest
9 голосов
/ 20 сентября 2010

Моя проблема очень похожа на эту: Вставка полей через Spring в объекты, загруженные Hibernate

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

Моя весенняя версия 3.0.4.

Что соответствует eventListeners в мире JPA?

Пример кода из исходного поста:

class Student {
   int id; //loaded from DB
   String name; //loaded from DB
   int injectedProperty; //Inject via Spring
   transient Service serviceImpl; //Inject via Spring
}

Я знаю, что могут быть решения аспектаJ, но я бы предпочел решение на основе чистой Java. Спасибо.

1 Ответ

8 голосов
/ 20 сентября 2010

Каковы соответствующие EventListeners в мире JPA?

JPA имеет Entity Listeners (и методы обратного вызова). Из спецификации JPA 2.0:

3.5 Слушатели сущностей и методы обратного вызова

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

(...)

Класс прослушивателя сущности должен иметь открытый конструктор без аргументов.

Слушатели сущности не имеют состояния. Жизненный цикл слушателя сущности не определено.

Следующие правила применяются к жизненному циклу Обратные вызовы:

  • Методы обратного вызова жизненного цикла могут выдавать непроверенные / исключительные ситуации времени выполнения. исключение во время выполнения, вызванное обратным вызовом метод, который выполняется в пределах транзакция вызывает эту транзакцию быть отмеченным для отката.
  • Обратные вызовы жизненного цикла могут вызывать JNDI, JDBC, JMS и корпоративные компоненты.
  • Как правило, метод жизненного цикла переносимого приложения не должен вызвать EntityManager или Query операции, доступ к другой сущности экземпляры или изменить отношения в том же контексте постоянства. метод обратного вызова жизненного цикла может изменить несвязанное состояние сущность, на которую она вызывается.

(...)

3.5.1 Методы обратного вызова жизненного цикла

Методы обратного вызова жизненного цикла объекта могут быть определенным в классе слушателя сущности и / или непосредственно в классе сущности или сопоставленный суперкласс.

Методы обратного вызова жизненного цикла с аннотациями, обозначающими события обратного вызова, для которых они вызваны или сопоставлены с обратным вызовом событие с использованием дескриптора XML.

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

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

void <METHOD>()

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

void <METHOD>(Object)

Аргумент Object является сущностью экземпляр для которого вызывается метод обратного вызова вызывается. Это может быть объявлено как фактический тип объекта.

Методы обратного вызова могут иметь открытый, закрытый, защищенный доступ или доступ на уровне пакета, но не должны быть static или final.

(...)

Вот пример (из спецификации):

@Entity
@EntityListeners(com.acme.AlertMonitor.class)
    public class Account {
    Long accountId;
    Integer balance;
    boolean preferred;
    @Id
    public Long getAccountId() { ... }
    ...
    public Integer getBalance() { ... }
    ...
    @Transient // because status depends upon non-persistent context
    public boolean isPreferred() { ... }
    ...
    public void deposit(Integer amount) { ... }
    public Integer withdraw(Integer amount) throws NSFException {... }

    @PrePersist
    protected void validateCreate() {
        if (getBalance() < MIN_REQUIRED_BALANCE)
            throw new AccountException("Insufficient balance to open an account");
    }

    @PostLoad
    protected void adjustPreferredStatus() {
        preferred = (getBalance() >= AccountManager.getPreferredStatusLevel());
    }
}

public class AlertMonitor {
    @PostPersist
    public void newAccountAlert(Account acct) {
        Alerts.sendMarketingInfo(acct.getAccountId(), acct.getBalance());
    }
}

В вашем случае вам, вероятно, понадобятся PostLoad методы обратного вызова.

См. Также Глава 6. Слушатели сущностей и методы обратного вызова в документации по Hibernate Entity Manager.

Но, проще говоря, то, что вы хотите сделать, - это не так просто с JPA, и наилучшим вариантом может быть использование класса AspectJ с использованием аннотации @Configurable.

Ссылки

  • JPA 2.0 Спецификация
    • Раздел 3.5 «Слушатели сущностей и методы обратного вызова»
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...