jpa 2.0没有注入EntityManager

时间:2016-08-31 22:51:41

标签: jpa annotations apache-karaf

我有一个简单的JPA 2.0注释实现无法正常工作。这是作为服务器在karaf 4.0.5中运行的。下面列出了persistence.xml,blueprint.xml和类的相关摘录。该例外列在底部。

问题是EntityManager em始终为空。我预计这会被蓝图注入。

有谁可以指出我出错的地方?

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

异常

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]

2 个答案:

答案 0 :(得分:0)

您的数据源配置似乎缺失。您正在使用osgi.jndi.service.name =无法声明的MotorDB。所以没有服务实现javax.sql.DataSource

必须有类似于以下使用Oracle的示例。 相应地更改其他DBMS:

...
<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>
...

此外,您可能必须在persistence.xml中指定持久性提供程序。如果你在Oracle 10g中使用了hibernate,它看起来会像这样:

<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" />
   ...

然后,您可以将数据源链接到您的服务:

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

如果仍然没有注入EM提供一个setter:

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

AFAIK有/是一个错误,只有在设置器可用时,属性注入才有效。

答案 1 :(得分:0)

原因是karaf 4.0.5和openjpa 2.4.1的问题。它已在karaf 4.0.6中得到解决