Как я могу указать, какую фабрику диспетчера сущностей использовать, не изменяя класс DAO? - PullRequest
0 голосов
/ 20 февраля 2020

У меня есть приложение Java 7 / Spring 3.2.17, которое должно подключаться к двум разным базам данных, поэтому у меня есть два разных файла персистентности. 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]: ожидается один соответствующий компонент, но найден 2 : emf1, emf2

Я частично решил это, указав , какую единицу хранения я хочу использовать , например:

@PersistenceContext(unitName = "pu1")
private EntityManager entityManager;

public void setEntityManager (...) { ... }

Это решило проблему для классов, подключающихся к первой базе данных. Моя проблема в том, что классы для другой БД являются частью сторонней библиотеки, поэтому я не могу изменить их, добавив атрибут unitName. Есть ли другой способ сделать это?


Я испробовал несколько вариантов, но все они приводят к одному и тому же сообщению об ошибке:

  1. Расширение класса, чтобы я мог "переопределить аннотацию" :
public class MyDao extends TheDaoThatICannotModify {
    @Override
    @PersistenceContext(unitName = "pu2")
    public void setEntityManager (EntityManager em) {
        super.setEntityManager(em);
    }
}
Создание экземпляра EM и его введение самостоятельно:
<bean id="entityManager2" factory-bean="emf2" factory-method="getObject" />

<bean id="myDao" class="com.foo.TheDaoThatICannotModify">
    <property name="entityManager" ref="entityManager2" />
</bean>

Добавление атрибута primary="true" к моему бобу emf2primary="false" к emf1).

Добавление атрибута autowire-candidate="false" к моему emf1 боб.

1 Ответ

0 голосов
/ 21 февраля 2020

Я получил это ... используя Spring инъекцию только с моими собственными классами, и передавая EM к злым DAOs себе:

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

Я не знаю как назвать этот шаблон: фабрика, синглтон, обертка? Это не подходит ни к одной из этих категорий, это странная комбинация их. Что, вероятно, не является хорошим знаком, похоже на огромный запах кода, и я бы предпочел его избежать. Но, по крайней мере, это работает, так что нет лучшего решения ...

...