Jacob
Jacob

Reputation: 14741

NullPointerException when accessing EntityManager

I am using Hibernate4,Spring3 and JSF2 for a small application and Weblogic 10.3.6 as Apps server.

In order to enable JPA2 I have added the following in commEnv.cmd

@rem Enable JPA 2.0 functionality on WebLogic Server
set PRE_CLASSPATH=%BEA_HOME%\modules\javax.persistence_1.1.0.0_2-0.jar;
%BEA_HOME%\modules\com.oracle.jpa2support_1.0.0.0_2-1.jar

When I run my application I am getting null pointer exception at the following line. How can I resolve this?

CriteriaBuilder cb = entityManager.getCriteriaBuilder();

My DAO

@Named
public class RequestDAOImpl implements RequestDAO {

protected EntityManager entityManager;

public void getRequest(RequestQueryData data){
        Map<String, String> filters = data.getFilters();
        int start = data.getStart();
        int end = data.getEnd();
        String sortField = data.getSortField();
        QuerySortOrder order = data.getOrder();

        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<Request> c = cb.createQuery(Request.class);
        Root<Request> emp = c.from(Request.class);
        c.select(emp);
                ...... other code

applicationContext.xml

<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
        <property name="scopes">
            <map>
                <entry key="view">
                    <bean class="org.primefaces.spring.scope.ViewScope" />
                </entry>
            </map>
        </property>
    </bean>
    <context:component-scan base-package="net.test" />
    <!-- Data Source Declaration -->
    <bean id="DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
        <property name="driverClass" value="oracle.jdbc" />
        <property name="jdbcUrl"
            value="jdbc:oracle:thin:@server:1521:ORCL" />
        <property name="user" value="scott" />
        <property name="password" value="tiger" />
        <property name="maxPoolSize" value="10" />
        <property name="maxStatements" value="0" />
        <property name="minPoolSize" value="5" />
    </bean>     
    <!-- Session Factory Declaration -->
    <bean id="SessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="DataSource" />
        <property name="annotatedClasses">
            <list>
                <value>net.test.model.Request</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.query.factory_class">org.hibernate.hql.internal.classic.ClassicQueryTranslatorFactory
                </prop>
            </props>
        </property>
    </bean>
    <!-- Enable the configuration of transactional behavior based on annotations -->
    <tx:annotation-driven transaction-manager="txManager" />
    <!-- Transaction Manager is defined -->
    <bean id="txManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="SessionFactory" />
    </bean>

Update 1

applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <!-- Spring view scope customized -->

    <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
        <property name="scopes">
            <map>
                <entry key="view">
                    <bean class="org.primefaces.spring.scope.ViewScope" />
                </entry>
            </map>
        </property>
    </bean>
    <context:component-scan base-package="net.test" />
    <!-- Data Source Declaration -->
    <bean id="DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
        <property name="driverClass" value="oracle.jdbc" />
        <property name="jdbcUrl"
            value="jdbc:oracle:thin:@server:1521:ORCL" />
        <property name="user" value="scott" />
        <property name="password" value="tiger" />
        <property name="maxPoolSize" value="10" />
        <property name="maxStatements" value="0" />
        <property name="minPoolSize" value="5" />
    </bean>
      <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
    <!-- JPA Entity Manager Factory -->
    <bean id="entityManagerFactory" 
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
         <property name="dataSource" ref="DataSource" />
         <property name="packagesToScan" value="net.test.model" />
         <property name="jpaVendorAdapter">
      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">  
       </bean>
   </property>         
      </bean> 
      <bean id="defaultLobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" />        
    <!-- Session Factory Declaration -->
    <bean id="SessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="DataSource" />
        <property name="annotatedClasses">
            <list>
                <value>net.test.model.Request</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.query.factory_class">org.hibernate.hql.internal.classic.ClassicQueryTranslatorFactory
                </prop>
            </props>
        </property>
    </bean>
    <!-- Enable the configuration of transactional behavior based on annotations 
    <tx:annotation-driven transaction-manager="txManager" />-->
    <!-- Transaction Manager is defined 
    <bean id="txManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="SessionFactory" />
    </bean>-->

     <!-- Transaction Config -->
    <bean id="transactionManager"
          class="org.springframework.orm.jpa.JpaTransactionManager">
          <property name="entityManagerFactory" ref="entityManagerFactory" />
          </bean>   

          <bean id="txManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="SessionFactory" />
    </bean>         

    <tx:annotation-driven transaction-manager="transactionManager"/>  
    <tx:annotation-driven transaction-manager="txManager"/>             

     <context:annotation-config/>


    <bean id="hibernateStatisticsMBean" class="org.hibernate.jmx.StatisticsService">
        <property name="statisticsEnabled" value="true" />
        <property name="sessionFactory" value="#{entityManagerFactory.sessionFactory}" />
    </bean>
    <bean name="ehCacheManagerMBean"
        class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" />

    <bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
        <property name="locateExistingServerIfPossible" value="true" />
    </bean>

    <bean id="jmxExporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
        <property name="server" ref="mbeanServer" />
        <property name="registrationBehaviorName" value="REGISTRATION_REPLACE_EXISTING"/>
        <property name="beans">
            <map>               
                <entry key="SpringBeans:name=hibernateStatisticsMBean" value-ref="hibernateStatisticsMBean" />
                <entry key="SpringBeans:name=ehCacheManagerMBean" value-ref="ehCacheManagerMBean" />
            </map>
        </property>
    </bean>

</beans>

Upvotes: 2

Views: 10025

Answers (1)

Apropos
Apropos

Reputation: 516

Your EntityManager doesn't appear to be wired into your DAO. Add @Autowired, @PersistenceContext or a ref in your XML. Note that to just use @Autowired, you'll have to specify EntityManager as a bean.

Another possibility: if your DAO isn't also specified as a bean (either in the XML or using one of the various @Component annotatons (probably @Repository), Spring won't know to wire things in, either.

Update: There's a couple different solutions here. Before those, though, make sure that you have

    <mvc:annotation-driven />

In one of your XMLs. This will enable the spring annotations and save you a lot of headache from editing XMLs. Note that you'll also need to update the xmlns and schemaLocation in the <beans> tag.

xmlns:mvc="http://www.springframework.org/schema/mvc"

and

   http://www.springframework.org/schema/mvc
   http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd

in the schemaLocation.

It looks like you're now specifying an EntityManagerFactory. That's a good start. You can now specify an EntityManager, too.

<bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

I can't vouch for your XML and EntityManagerFactory settings, though. You seem to have an </property> floating out there in the middle of nowhere.

I'm not sure how you're accessing your DAO. If it's already a bean and within the component-scan, you're good. If not, make sure to annotate your DAO class with @Repository and make sure its package is within the component-scan. Of course, if you don't already have it specified as a bean, that implies that you're possibly instantiating it elsewhere -- this is absolutely not how you want to be using your DAO. Should this be the case, I strongly recommend reading up on Spring's dependency injection.

Now you need to wire in your EntityManager. This can be done in two ways.

The first way requires that you specified it as a bean in your XML. If you've done that, just annotate your EntityManager field.

@Autowired
protected EntityManager entityManager;

Alternatively, since you're specifying a DataSource in your XML, you SHOULD be able to reference it by using @PersistenceContext and passing it a value of the ID.

@PersistenceContext(name="DataSource")
protected EntityManager entityManager;

I've never really used the latter method, but I've seen it done that way. I normally specify an EntityManager bean in the XML and use @Autowired, as described in the former method.

Upvotes: 3

Related Questions