Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > @PersistentContext инжектирует null


Автор: ki6opr 24.5.2010, 09:31
Доброго времени суток всем.
В общем возникла какая то непонятная для меня проблемма.
Есть сервер Jboss 5 на него задеплоин EAR в котором есть сешн бин
Код

@Stateless(name = "SimpleCRUDDAOBean")
public class SimpleCRUDDAOBean<T extends Serializable, ID extends Serializable>
        implements SimpleCRUDDAOLocal<T, ID> {

    @PersistenceContext(unitName = "domainPU")
    protected EntityManager manager;

    @PostConstruct
    public void init() {
        System.err.println("Container inject EntityManager: " + manager);
        System.err.println("Create EntityManager manually: " +
                (manager = Persistence.createEntityManagerFactory("domainPU").createEntityManager()));
    }
}

проблемма в том что через @PersistenceContext(unitName = "domainPU") инжектится null, но если создавать EntityManager ручками через фабрику то все замечательно работает.

persistence.xml
Код

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence  http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <persistence-unit name="domainPU" transaction-type="JTA">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>java:jdbc/myds</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
      <property name="hibernate.max_fetch_depth" value="1"/>
      <property name="org.hibernate.dialect.Dialect" value="org.hibernate.dialect.MySQL5Dialect"/>

      <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
      <property name="hibernate.connection.useUnicode" value="true"/>
      <property name="hibernate.connection.characterEncoding" value="UTF-8"/>
      <property name="hibernate.hbm2ddl.auto" value="update"/>
    </properties>
  </persistence-unit>
</persistence>



в гугле вагон примеров, где просто люди ошибались и создавали сешн бины руками, это не мой случай smile

PS сначала были ошибки что хибернэйту нужен был доступ к transactionManager'у, поправил и через руками созданного entitymanager запросы к базе выполняются.


Автор: Maksym 25.5.2010, 10:35
Проблема в том, что аппликейшн сервер на знает от твоем persistence unit'е и не соображает как его заинжектить. Ему надо помочь.
Для этого объявим простой data source, о котором будет знать JBoss. Если ты запускаешь его в дефолтной конфигурации, то для этого нужно положить дескриптор data source'а в server/default/deploy. Вот пример такого дескриптора для postgresql (для mysql полная аналогия):
Код

<?xml version="1.0" encoding="UTF-8"?>
<datasources>   
   <local-tx-datasource>
      <jndi-name>ds/mydatabase</jndi-name>
      <connection-url>jdbc:postgresql://localhost:5432/mydatabase</connection-url>
      <driver-class>org.postgresql.Driver</driver-class>
      <user-name>admin</user-name>
      <password>password</password>
      <min-pool-size>5</min-pool-size>
      <max-pool-size>20</max-pool-size>
      <idle-timeout-minutes>0</idle-timeout-minutes>
      <track-statements/>
      <prepared-statement-cache-size>32</prepared-statement-cache-size>
   </local-tx-datasource>
</datasources>

Теперь об источнике данных JBoss'у извесно.

После этого в в META-INF/persistence.xml твоего EJB проекта нужно объявить persistence-unit, который использует этот глобальный data source. Например так:
Код

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
    <persistence-unit name="MyPersistenceUnit">
        <jta-data-source>java:ds/mydatabase</jta-data-source>
                <jar-file>NameOfProjectsWithEntities.jar</jar-file>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>            
            <property name="hibernate.show_sql" value="false" />
            <property name="hibernate.format_sql" value="false" />  
        </properties>
    </persistence-unit>
</persistence>


После этого инжектить entity manager в любом ejb можно без дополнительных параметров:
Код

    @PersistenceContext
    private EntityManager em;





Автор: ki6opr 26.5.2010, 06:43
Спасибо Maksym.
в общем я все поборол, но не таким образом.

почему то когда грузилось приложение, коряво подгружался jar с сущностями и персистент юнитом, который лежит в нем. entity грузились а вот юнит нет.
я так подозреваю что когда я пытался создавать руками EntityManager то ear сканировался (могу только предполагать) и persistent unit находился , подгружался и все создавалось.

решилось дописыванием jar'a с сущностями в application.xml в качестве модуля
Код

<?xml version="1.0" encoding="UTF-8"?>
<application version="5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd">
  <display-name>Billing</display-name>
  <module>
    <ejb>domain-ejb.jar</ejb>
  </module>
  <module>
    <ejb>service-ejb.jar</ejb>
  </module>
</application>


просто приходится писать под два сервера (Glassfish и JBoss) и постоянно вылазиют всякие костыли, к примеру с таким дескриптором как выше глассфиш сломается, для него domain-ejb.jar нужно указывать как библиотеку а не модуль.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)