我正在尝试write some JUnit tests for a Spring 2.0.7 application。
在我的应用程序上下文XML文件中,我有这个bean:
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
id="entityManagerFactory"> ... </bean>
在我的DAO中,我只是为实体管理器注释了setter,Spring完成了所有的魔术:
@PersistenceContext
public void setEntityManager(EntityManager em) {
this.em = em;
}
在Spring 2.5+中,我只想用@RunWith(SpringJUnit4ClassRunner.class)
和@ContextConfiguration(locations = {"/applicationContext-test.xml"})
注释我的测试类。但我的春天版本太旧了,没有SpringJUnit4ClassRunner
。因此,我的JUnit测试没有Spring魔法。相反,我自己这样做:
// Load the XML file myself
XmlWebApplicationContext appContext = new XmlWebApplicationContext();
appContext.setConfigLocations(new String[] { "classpath:applicationContext-test.xml" });
appContext.refresh();
// Retrieve the entity manager factory
Object obj = appContext.getBean("entityManagerFactory");
// ***** The following line throws an exception: *****
LocalContainerEntityManagerFactoryBean aux = (LocalContainerEntityManagerFactoryBean) obj;
EntityManagerFactory emf = aux.getObject();
// Instantiate the EM and inject it into the DAOs
EntityManager em = emf.createEntityManager();
myDAO.setEntityManager(em);
我得到一个ClassCastException:当我尝试将obj
强制转换为aux
时,无法转换$ Proxy23 ...异常。但是,如果我在Eclipse中设置断点并检查obj
,它实际上是LocalContainerEntityManagerFactoryBean的一个实例。
我试过this approach,我在这里看到了很多问题。但是,AopUtils.isJdkDynamicProxy(obj)
返回false。此外,即使试图施放(Advised) obj
也会引发同样的异常。
我也尝试将obj
投射到FactoryBean,这是one of the interfaces implemented by LocalContainerEntityManagerFactoryBean ......是的,它抛出相同的异常。这是令人困惑的,因为几乎每个“类强制转换异常代理”的答案都说“你只能转换为接口而不是类”。
所以,我的问题是:
emf = Persistence.createEntityManagerFactory("myPersistenceUnit");
em = emf.createEntityManager();
这工作正常,但我丢失了applicationContext-test.xml文件中定义的<aop:config>
和<tx:advice>
条目。
您可以使用另一版本的getBean(...)
方法更严格地定义所需类型,请参阅official Spring 2.0 JavaDoc:
public Object getBean(String name, Class requiredType)
其中说明:
requiredType - bean必须匹配的类型。可以是实际类的接口或超类,也可以是任何匹配的null。例如,如果值为Object.class,则此方法将成功返回实例的任何类。
因此,要解决使用强制转换的问题,您需要以这种方式实现它:
// Retrieve the entity manager factory
EntityManagerFactory emf = (EntityManagerFactory)
appContext.getBean("entityManagerFactory", javax.persistence.EntityManagerFactory.class);
有了这个,您将直接检索“中性”EMF
,与JPA规范中描述的接口兼容。在运行时,这将是一个代理对象,但您可以按照原先的预期方式使用它:
// Instantiate the EM and inject it into the DAOs
EntityManager em = emf.createEntityManager();
// ... whatever comes here - most likely: doing some CRUD operations...
希望能帮助到你。