Инъекция CDI в спящие сущности - PullRequest
3 голосов
/ 15 декабря 2011

Мы используем CDI (JSR 299) в нашем приложении (JSF2 / Seam3.0 / Hibernate 3.5.6 / GlassFish 3.1.1)

Хотя мы не можем вводить ресурсы (вспомогательные POJO) в нашиуправляемые bean-компоненты, использующие @Inject, мы не можем сделать то же самое в наших классах Hibernate Entity.

У нас есть базовый класс сущности (@MappedSuperclass), из которого происходят все объекты сущностей.Инъекция CDI не выполняется в обоих классах.

@MappedSuperclass
public class BaseBusinessObject implements Serializable
{     
    @Inject
    private TestClass testClass; //FAILS
}


@Entity
@NamedQueries({ @NamedQuery(name = "Account.findAll", query = "SELECT b FROM Account b") })
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Account extends BaseBusinessObject
{
    @Inject
    private TestClass testClass; //FAILS

}

Похоже, что это может быть ограничение с CDI.Кто-нибудь может подтвердить, работает ли CDI с объектами Hibernate.

Будем благодарны за любые материалы.

Спасибо и С уважением

Ответы [ 3 ]

3 голосов
/ 15 декабря 2011

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

Желаете ли вы, чтобы CDI создал единую сущность гибернации для всего приложения и внедрил в нее ваших помощников / служб / что угодно??Или вы хотите, чтобы CDI внедрял материал в любую сущность, созданную вами с помощью «new Entity ()»?


Редактировать: Как правило, утилиты Date Time не содержат состояния ине нужны никакие вставленные данные CDI, так почему бы не сделать все методы статичными, как то, что мы находим в apache commons DateUtils?

Если вашим датам Time Time требуется состояние, сделайте его одиночным (но позаботьтесь опроблемы параллелизма).

Если ваши утилиты Date Time должны вызывать другие bean-объекты CDI (поэтому они не могут быть статичными), тогда вы бы предпочли сделать его одноэлементным и внедрить в одноэлементный компонент другие bean-компоненты CDI.

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

2 голосов
/ 15 декабря 2011

Плохо практиковать систематическое использование сущности JPA в качестве компонента CDI (но возможно, если вы захотите). Это в основном из-за «C» CDI: Context.

Все реализации CDI используют прокси-механизм для обработки внедрения компонента с заданной областью действия в компонент с другой областью действия. И так как большинство реализаций JPA используют также прокси для управления каким-то механизмом (например, Lazy Loading), у вас будет множество прокси в вашем классе с разными жизненными циклами: беспорядок!

Документация по сварке, как даже угасание этой проблемы: Глава 5. Области применения и контексты

Однако в некоторых случаях было бы полезно представить объект как компонент CDI, но вы бы предпочли использовать для этого производителя:

@Produces
@Named
@RequestScoped
private MyEntity produceMyEntity()
{
     return new MyEntity(); //or any JPA lookup you'll need
}

Этот способ наиболее удобен, но вы должны быть очень осторожны при смешивании управляемых объектов и CDI

0 голосов
/ 08 сентября 2018

вы можете запускать события CDI в объекте JPA или EntityListener.и вставьте TestClass в класс, который содержит метод Observed.Посмотрите следующую ссылку для получения дополнительной информации: http://blogs.bytecode.com.au/glen/2014/01/09/firing-cdi-events-from-a-jpa-entitylistener.html

Вы также можете получить доступ к BeanManager следующим образом (вместо поиска JNDI)

CDI.Current().getBeanManager()

...