Spring @ PersistenceContext как вручную внедрить диспетчер объектов в мой GenericDAO

#spring #entitymanager

#spring #entitymanager

Вопрос:

Всем привет: я прочитал ссылку spring на этот счет.

Я бы предпочел использовать @PersistenceContext в моем DAO для внедрения общего менеджера транзакционных сущностей, но поскольку я использую шаблон GenericDaoJpaImpl для двух entityManagerFactories, которые указывают на 2 разные единицы сохранения, я не могу его использовать.

Итак, прямо сейчас в моем приложении у меня есть эта конфигурация:

entityManagerFactoryies:

 <bean id="entityManagerFactoryIban0" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceXmlLocation" value="classpath:META-INF/contratto-persistence-iban0.xml" />
    </bean>

    <bean id="entityManagerFactoryCont0" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceXmlLocation" value="classpath:META-INF/contratto-persistence-cont0.xml" />
    </bean>

    <bean abstract="true" id="abstractDaoJpaImplIban0" lazy-init="false">
        <property name="entityManagerFactory" ref="entityManagerFactoryIban0" />
    </bean>

    <bean abstract="true" id="abstractDaoJpaImplCont0" lazy-init="false">
        <property name="entityManagerFactory" ref="entityManagerFactoryCont0" />
    </bean>
  

Тогда каждый из моих DAO является экземпляром GenericDaoImpl:

 @Repository
public class GenericDaoJpaImpl<T, ID extends Serializable> implements GenericDao<T, ID> {
    private Class<T> entityClass;

    private EntityManagerFactory entityManagerFactory;

    public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
        this.entityManagerFactory = entityManagerFactory;
    }

    public GenericDaoJpaImpl() {
        super();
    }

    public GenericDaoJpaImpl(Class<T> entityClass) {
        super();
        this.entityClass = entityClass;
    }

    /**
     * @see it.alten.intesasanpaolo.contratto.dao.common.GenericDao#getItemByID(java.io.Serializable)
     */
    @Override
    public T getItemByID(ID id) {
        EntityManager em = entityManagerFactory.createEntityManager();
        return em.find(entityClass, id);

    }
  

Я создаю свой dao через spring таким образом:

 <bean id="eventMessageDao" parent="abstractDaoJpaImplCont0" class="it.alten.intesasanpaolo.contratto.dao.common.GenericDaoJpaImpl">
        <constructor-arg>
            <value>it.alten.intesasanpaolo.contratto.domain.event.OnlineEventMessage</value>
        </constructor-arg>
    </bean>
  

Теперь я хотел бы изменить GenericDaoJpaImpl, как описано в документации spring, чтобы он не был связан с EntityManagerFactory, из которого я должен каждый раз создавать EntityManager, а непосредственно с EntityManager.

Я хотел бы определить его в контексте таким образом, чтобы я мог внедрить его в правильный абстрактный dao, который будет расширен из каждого dao.

 <bean abstract="true" id="abstractDaoJpaImplIban0" lazy-init="false">
        <property name="entityManagerFactory" ref="entityManagerFactoryIban0" />
    </bean>
  

Как я могу этого добиться?

с уважением, Массимо

Ответ №1:

Вы можете использовать SharedEntityManagerBean для создания транзакции EntityManager из EntityManagerFactory :

 <bean id="entityManagerFactoryIban0" 
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">            
    ... 
</bean> 

<bean id="entityManagerIban0"  
    class="org.springframework.orm.jpa.support.SharedEntityManagerBean">            
    <property name="entityManagerFactory" ref="entityManagerFactoryIban0" />
</bean> 

<bean abstract="true" id="abstractDaoJpaImplIban0" lazy-init="false">
    <property name="entityManager" ref="entityManagerIban0" />
</bean> 
  

Ответ №2:

Вы можете указать имя единицы сохраняемости в конфигурации xml, используя SharedEntityManagerBean , как показано ниже:

 <bean id="testDao" class="com.test.persistence.dao.BaseDAO">
    <property name="entityManager">
        <bean class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
            <property name="persistenceUnitName" value="persistence-test-unit" />
        </bean>
    </property>
</bean>
  

конечно, вы можете использовать SharedEntityManagerBean как отдельный компонент

Здесь я внедряю entityManager в BaseDAO , как вы делаете, используя @PersistenceContext(unitName="...")