gpt4 book ai didi

java - JPA EntityManager 没有被 Spring 4 注入(inject)

转载 作者:太空宇宙 更新时间:2023-11-04 14:06:30 25 4
gpt4 key购买 nike

在专门使用 guice 工作几次之后,我尝试使用注释重新学习当前版本的 spring 框架。但是,我似乎无法让 spring 在测试期间使用 @PersistenceContext 注释注入(inject) EntityManager 。这是我的设置:

持久性.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
}

产品DAOImpl

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

最后,我尝试注入(inject)的测试类:

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 类型的位和 bob。

但是每当我运行测试时,我都会在 EntityManager 上收到 NullPointerException。该 bean 正在被实例化,但尚未连接到 DAO。

最佳答案

已解决:这里的问题是我试图像对待SessionFactory一样对待EntityManager。 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;
}
}

关于java - JPA EntityManager 没有被 Spring 4 注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28810646/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com