2016-08-31 3 views
0

J'ai une implémentation simple des annotations JPA 2.0 qui ne fonctionne pas. Cela fonctionne en karaf 4.0.5 en tant que serveur. Ci-dessous sont énumérés les extraits pertinents de persistence.xml, blueprint.xml et la classe. L'exception est répertoriée en bas.jpa 2.0 n'injecte pas EntityManager

Le problème est que le EntityManager em est toujours nul. Je m'attendais à ce que cela soit injecté par blueprint. Est-ce que quelqu'un peut signaler où je me suis trompé?

Classe

import javax.persistence.PersistenceContext; 
import javax.transaction.Transactional; 

@Transactional 
public class LookupMfgService implements ILookupMfgService { 
    private static Logger logger = LoggerFactory.getLogger(LookupMfgService.class); 
    @PersistenceContext(unitName = "pu_motordb3") 
    private EntityManager em; 

    @Override 
    public List<String> getPreferredMfgNames() throws BusinessException { 
     List<String> list = new ArrayList<>(); 

     try { 
    // em is null here so NPE thrown 
      TypedQuery<String> q = em.createNamedQuery("listMfgPreferredNames", String.class); 
      list = q.getResultList(); 
     } catch (Throwable t) { 
      logger.error("Error selecting list of manufacturers", t); 
      throw JpaExceptionFactory.createGeneralError(t, this.getClass().getName()); 
     } 

     return list; 
    } 

    public void setEm(EntityManager entityManager) { 
     logger.debug(this.getClass().getName() + ".setEntityManager()"); 
     logger.debug("setEntityManager called with " + (entityManager == null ? "null" : entityManager.toString())); 
     this.em = entityManager; 
    } 
} 

DataSource.xml

<blueprint default-activation="eager" 
    xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0" 

    xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0 
      http://www.w3.org/2001/XMLSchema-instance http://www.w3.org/2001/XMLSchema-instance 
      http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0 http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0 "> 

    <bean id="dataSource" class="org.postgresql.ds.PGPoolingDataSource" destroy-method="close"> 
     <property name="serverName" value="XXX"/> 
     <property name="user" value="XXX"/> 
     <property name="password" value="XXX"/> 
     <property name="dataSourceName" value="pgConnectionPool"/> 
     <property name="initialConnections" value="5"/> 
     <property name="maxConnections" value="50" /> 
    </bean> 

    <service interface="javax.sql.DataSource" ref="dataSource"> 
    <service-properties> 
      <entry key="osgi.jndi.service.name" value="MotorDB"/> 
    </service-properties> 
    </service> 
</blueprint> 

Blueprint.xml

<blueprint default-activation="eager" 
    xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0" 
    xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0" xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0" 
    xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0" 
    xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd 
     http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0 http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0 
     http://aries.apache.org/xmlns/transactions/v2.0.0 http://aries.apache.org/xmlns/transactions/v2.0.0 
     http://aries.apache.org/xmlns/jpa/v2.0.0 http://aries.apache.org/xmlns/jpa/v2.0.0 
     http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0 http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"> 

    <jpa:enable /> 
    <tx:enable /> 

    <service id="mfgLookupService" ref="mfgLookupEntityImpl" interface="ILookupMfgService"/> 

</blueprint> 

persistence.xml

<?xml version="1.0" encoding="UTF-8" ?> 
<persistence 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_2_0.xsd" 
    version="2.0"> 

    <persistence-unit name="pu_motordb3" transaction-type="JTA"> 
    <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> 
    <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=MotorDB)</jta-data-source> 
     Classes listed here 
    </persistence-unit> 
</persistence> 

Karaf log

2016-09-01 09:45:48,689 | INFO | PersistenceBundleTracker | 90 - org.apache.aries.jpa.container - 2.3.0 | Found persistence unit reference3 in bundle entity with provider org.apache.openjpa.persistence.PersistenceProviderImpl. 
2016-09-01 09:45:48,695 | INFO | PersistenceBundleTracker | 90 - org.apache.aries.jpa.container - 2.3.0 | Found persistence unit pu_motordb3 in bundle entity with provider org.apache.openjpa.persistence.PersistenceProviderImpl. 
2016-09-01 09:45:48,695 | INFO | PersistenceBundleTracker | 90 - org.apache.aries.jpa.container - 2.3.0 | Persistence units added for bundle com.easa.server.entity event 128 

Exception

2016-08-31 18:42:49,286 | ERROR | nelWorkerThread0 | LookupMfgService     | Error selecting list of manufacturers 
java.lang.NullPointerException 
     at LookupMfgService.getPreferredMfgNames(LookupMfgService.java:93) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[:1.8.0_91] 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)[:1.8.0_91] 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[:1.8.0_91] 
     at java.lang.reflect.Method.invoke(Method.java:498)[:1.8.0_91] 
     at ch.ethz.iks.r_osgi.impl.ChannelEndpointImpl.handleMessage(ChannelEndpointImpl.java:1265)[69:ch.ethz.iks.r_osgi.remote:1.0.8.RC1_v20160823-2221] 
     at ch.ethz.iks.r_osgi.impl.ChannelEndpointImpl$2.run(ChannelEndpointImpl.java:315)[69:ch.ethz.iks.r_osgi.remote:1.0.8.RC1_v20160823-2221] 
     at ch.ethz.iks.r_osgi.impl.ChannelEndpointImpl$1.run(ChannelEndpointImpl.java:280)[69:ch.ethz.iks.r_osgi.remote:1.0.8.RC1_v20160823-2221] 

Répondre

0

La cause était un problème avec karaf 4.0.5 et openjpa 2.4.1. Il a été résolu en karaf 4.0.6

0

La configuration de votre source de données semble manquer. Vous utilisez osgi.jndi.service.name = MotorDB qui n'est déclaré nulle part. Il n'y a donc pas de service implémentant javax.sql.DataSource

Il doit y avoir quelque chose de similaire à l'exemple suivant qui utilise Oracle. Modifier en conséquence pour d'autres SGBD:

... 
<bean id="dataSourceBeanMfgLookupService" class="oracle.jdbc.pool.OracleDataSource"> 
    <property name="URL" value="???"/> 
    <property name="user" value="???"/> 
    <property name="password" value="???"/> 
</bean> 

<service id="dataSourceMfgLookupService" interface="javax.sql.DataSource" ref="dataSourceBeanMfgLookupService"> 
    <service-properties> 
    <entry key="osgi.jndi.service.name" value="MotorDB" /> 
    </service-properties> 
</service> 
... 

De plus vous pouvez avoir à spécifier une persistance fournisseur dans votre persistence.xml. Si vous avez utilisé Mise en veille prolongée avec Oracle 10g il ressemblerait un peu comme ceci:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" ...> 

    <provider>org.hibernate.ejb.HibernatePersistence</provider> 

    ... 

    <properties> 
     <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" /> 
     <property name="hibernate.temp.use_jdbc_metadata_defaults" value="false" /> 
    ... 

Ensuite, vous pouvez lier votre source de données à votre service:

<bean id="mfgLookupEntityImpl" class="LookupMfgService"> 
    <jpa:context property="em" unitname="pu_motordb3" /> 
    <tx:transaction method="*" value="Required" /> 
</bean> 

Si cela ne fonctionne toujours pas injecter l'EM fournir un setter:

public void setEm(EntityManager entityManager) { 
    this.em = entityManager; 
} 

AFAIK il y avait/est un bug que l'injection de propriété ne fonctionnait que si un setter était disponible.

+0

Oliver ... merci pour votre commentaire et commentaires! J'ai un blueprint.xml séparé qui crée la source de données et la référence jndi. Je l'ai inclus ci-dessus. J'ai ajouté le fournisseur et changé/ajouté le setter. Toujours obtenir un pointeur null lorsque vous essayez de référencer le EntityManager. L'annotation doit gérer l'injection au lieu d'ajouter directement dans blueprint.xml –