开发者

JPA's context injection

开发者 https://www.devze.com 2022-12-15 01:36 出处:网络
I\'m trying to use JPA\'s Context Injection. Currently my code fails to have the context injected, throwing a NullPointerException:

I'm trying to use JPA's Context Injection. Currently my code fails to have the context injected, throwing a NullPointerException:

Exception in thread "main" java.lang.NullPointerException at learn.spring.dao.ListingDao.findById(ListingDao.java:19)

Below is my code, anyone see what is wrong/missing? Thanks.

Spring Configuration xml:

<beans ....>

<tx:annotation-driven />
<context:annotation-config />
<aop:aspectj-autoproxy />

<bean id="listingDao" class="learn.spring.dao.ListingDao" />

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
 <property name="driverClassName" value="com.mysql.jdbc.Driver" />
 <property name="url" value="jdbc:mysql://xxx.xxx.xxx.xxx/xxxxx" />
 <property name="username" value="xxxxxx" />
 <property name="password" value="xxxxxx" />
</bean>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
 <property name="persistenceUnitName" value="learnSpring" />
 <property name="dataSource" ref="dataSource" />
 <property name="jpaVendorAdapter">
  <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
   <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
   <property name="showSql" value="true" />
   <property name="generateDdl" value="true" />
  </bean>
 </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
 <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
..开发者_开发百科.
</beans>

DAO class:

package learn.spring.dao;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.transaction.annotation.Transactional;

import learn.spring.model.Registration;

@Transactional
public class ListingDao {
 public ListingDao() {}

 @PersistenceContext
 private EntityManager entityManager;

 public Registration findById(int id) {
  Query query = entityManager.createQuery("FROM Registration r WHERE r.memberId = ?1");
  query.setParameter(1, id);
  return (Registration) query.getSingleResult();
 }
}

peristence.xml file:

<?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_1_0.xsd"
version="1.0">

<persistence-unit name="learnSpring" />

</persistence>

Class w/ "main" method:

public class Performance {

 public static void main(String[] args){
  ApplicationContext context = new ClassPathXmlApplicationContext("learn-spring.xml");
  Performer performer = (Performer) context.getBean("musician");
  performer.perform();
  ListingDao listingDao = new ListingDao();
  Registration registration = listingDao.findById(1);
  System.out.println("Member id = " + registration.getMemberId() + " Name = " + registration.getFirstName() + " " + registration.getLastName());
 }

}


Your problem is that your ListingDao isn't part of the spring context.

All the classes which you want to benefit from the spring's dependecy injection must be instantiated by spring. When you instantiate your ListingDao with the new operator, your object isn't part of the spring context and it doesn't receive an automatic EntityManager.

So the solution would be to get the ListingDao from the context, like you did with the performer:

ListingDao listingDao = (ListingDao) context.getBean("listingDao");

As a sidenote - avoid accessing the spring context directly. i.e. avoid lines like the above. Use annotations to inject your dependencies, rather than requesting them, because you are thus turning a Dependency Injection framework into a Service Locator.


When you instantiate ListingDAO, you're doing it outside of the spring context - so spring never gets a chance to wire up the EntityManager.

You should replace:

  ListingDao listingDao = new ListingDao();

with:

  ListingDao listingDao = (ListingDao) context.getBean("listingDao");
0

精彩评论

暂无评论...
验证码 换一张
取 消