1
經過幾次獨家使用guice之後,我試圖在當前版本中使用註釋重新學習Spring框架。不過,在測試過程中,我似乎無法使用@PersistenceContext
註釋來注入EntityManager
。這裏是我的設置:JPA EntityManager未被注入Spring 4
的persistence.xml
<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="com.whatever.shop.database" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.whatever.shop.domain.Product</class>
<class>com.whatever.shop.domain.Order</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver" />
<property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:mem:testdb" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
與持久化上下文一個通用的DAO實現
public abstract class GenericDAOImpl<T, PK extends Serializable> implements GenericDAO<T, PK> {
@PersistenceContext(unitName="com.whatever.shop.database")
private EntityManager entityManager;
private Class<T> entityType;
public GenericDAOImpl(Class<T> entityType) {
this.entityType = entityType;
}
@Override
public T getById(PK id) {
return entityManager.find(entityType, id);
}
// Some more methods
}
ProductDAOImpl
@Repository
public class ProductDAOImpl extends GenericDAOImpl<Product, Long> implements ProductDAO {
@PersistenceContext(unitName="com.whatever.shop.database")
private EntityManager entityManager;
public ProductDAOImpl() {
super(Product.class);
}
}
BeanConfig類,類定義的bean定義:
package com.whatever.shop.database;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = {"com.whatever.shop.database.jpa"})
public class BeanConfig {
@Bean
public EntityManagerFactory entityManagerFactory() {
return Persistence.createEntityManagerFactory("com.whatever.shop.database");
}
@Bean
public EntityManager entityManager() {
return entityManagerFactory().createEntityManager();
}
}
最後,測試類我試圖注入:
package com.whatever.shop.database.jpa;
import static org.junit.Assert.fail;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.whatever.shop.database.BeanConfig;
import com.whatever.shop.domain.Product;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={BeanConfig.class})
public class ProductDAOTest {
@Autowired
private ProductDAO productDao;
/**
* Test method for {@link com.whatever.shop.database.GenericDAOImpl#getById(java.lang.Object)}.
*/
@Test
public void testGetById() {
productDao.save(new Product());
}
}
我的這個應該怎麼理解的工作情況如下
- 測試運行着眼於應用程序上下文bean並創建
EntityManagerFactory
@ComponentScan
註釋應循環遍歷所有的DAO實現,檢測@Repository
註釋並執行PersistenceAnnotationBeanPostProcessor
類型的位和bobs。
但是每當我運行測試,我得到EntityManager
NullPointerException
。這個bean正在被實例化,但沒有連接到DAO中。
你不應該自己創建一個EntityManagerFactory。閱讀http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#orm-jpa – 2015-03-02 13:25:23