如何检索Spring的实体经理工厂?

问题描述 投票:2回答:1

我正在尝试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 ......是的,它抛出相同的异常。这是令人困惑的,因为几乎每个“类强制转换异常代理”的答案都说“你只能转换为接口而不是类”。

所以,我的问题是:

  • 有没有办法修复我发布的代码? (是的,我希望我可以升级Spring!但不,我不能)。
  • 或者:有没有其他方法可以使用XML文件中定义的EMF实例化实体管理器?请注意,我不能这样做:
emf = Persistence.createEntityManagerFactory("myPersistenceUnit");
em = emf.createEntityManager();

这工作正常,但我丢失了applicationContext-test.xml文件中定义的<aop:config><tx:advice>条目。

java spring classcastexception applicationcontext
1个回答
2
投票

您可以使用另一版本的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...

希望能帮助到你。

© www.soinside.com 2019 - 2024. All rights reserved.