如何在不修改DAO类的情况下指定要使用哪个实体管理器工厂



我有一个Java 7/Spring 3.2.17应用程序,它必须连接到两个不同的数据库,所以我有两个不同不同的persistence.xml文件,每个文件都声明自己的持久单元。

在我的应用程序上下文中,我定义了两个实体管理器工厂,例如:

<bean id="emf1" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="myDatasource1" />
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence1.xml" />
<property name="persistenceUnitName" value="pu1" />
...
</bean>

在我的DAO类中,我只让Spring注入实体管理器:

@PersistenceContext
private EntityManager entityManager;
public void setEntityManager (...) { ... }

Spring抱怨我有两个EM工厂,所以不知道该用哪一个:

NoUniqueBeanDefinitionException:未定义[javax.persistence.EntityManagerFactory]类型的合格bean:应为单个匹配bean,但找到2:emf1,emf2

我已经通过指定要使用的持久性单元部分解决了这个问题,如下所示:

@PersistenceContext(unitName = "pu1")
private EntityManager entityManager;
public void setEntityManager (...) { ... }

这解决了类连接到第一个数据库的问题。我的问题是,另一个DB的类是第三方库的一部分,所以我不能修改它们来添加unitName属性我还有别的办法吗


我尝试了一些选项,但所有选项都会导致相同的错误消息:

  1. 扩展类,这样我就可以"覆盖注释":
public class MyDao extends TheDaoThatICannotModify {
@Override
@PersistenceContext(unitName = "pu2")
public void setEntityManager (EntityManager em) {
super.setEntityManager(em);
}
}
  1. 实例化EM并自己注入:
<bean id="entityManager2" factory-bean="emf2" factory-method="getObject" />
<bean id="myDao" class="com.foo.TheDaoThatICannotModify">
<property name="entityManager" ref="entityManager2" />
</bean>
  1. primary="true"属性添加到我的emf2bean(以及将primary="false"添加到emf1(。

  2. autowire-candidate="false"属性添加到我的emf1bean中。

我开始工作了。。。通过只对我自己的类使用Spring注入,并将EM传递给自己的邪恶DAO

public class MyDaoSingletonFactoryIsh {
@PersistenceContext(unitName = "pu2")
private EntityManager em; // Injected by Spring
private static TheDaoThatICannotModify dao = null;
public TheDaoThatICannotModify getDAO() {
if (dao == null) {
dao = new TheDaoThatICannotModify();
dao.setEntityManager(em);
}
return dao;
}
}

我不知道如何调用这种模式:工厂、单例、包装器?它并不真正适合这些类别中的任何一个,这是它们的奇怪组合。这可能不是一个好兆头,它看起来像一股巨大的代码气味,我宁愿避免它。但至少它在起作用,所以,缺乏更好的解决方案。。。

最新更新