2015-03-02 6 views
1

После того, как пара работает исключительно с guice, я пытаюсь переделать Spring Framework в своей текущей версии, используя аннотации. Тем не менее, я, похоже, не могу получить весну, чтобы ввести EntityManager, используя аннотацию @PersistenceContext во время тестирования. Вот мои настройки:JPA EntityManager не был впрыснут весной 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 класса, для определения боб класса определяемых :

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()); 
    } 
} 

Мое понимание того, как это должно работать следующим образом

  1. Тест бегун смотрит на контекст приложения bean и создает EntityManagerFactory
  2. Аннотации @ComponentScan должны проходить через все мои реализации DAO, обнаруживая аннотацию @Repository и делая PersistenceAnnotationBeanPostProcessor Тип бит и бобы.

Но всякий раз, когда я запускаю тест, я получаю NullPointerException на EntityManager. Боб создается, но он не подключен к DAO.

+0

Вы не должны создавать EntityManagerFactory самостоятельно. Прочтите http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#orm-jpa –

ответ

0

Решено: Проблема в том, что я пытался обработать EntityManager, так как я бы SessionFactory. Spring нуждается в собственных фабричных объектах, чтобы присутствовать в контексте, поэтому он знает, что делать, когда он сталкивается с аннотацией @PersistenceContext. Изменения внесены в класс BeanConfig.

@Configuration 
@ComponentScan(basePackages = {"com.whatever.shop.database.jpa"}) 
public class BeanConfig { 

    @Bean 
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() { 
     LocalContainerEntityManagerFactoryBean thing = new LocalContainerEntityManagerFactoryBean(); 
     thing.setPersistenceUnitName("com.whatever.shop.database"); 
     return thing; 
    } 

    @Bean 
    public JpaTransactionManager transactionManager() { 
     JpaTransactionManager transactionManager = new JpaTransactionManager(); 
     transactionManager.setEntityManagerFactory(entityManagerFactory().nativeEntityManagerFactory); 
     return transactionManager; 
    } 
} 
Смежные вопросы