Внедрение одного из двух @PersistenceContext - PullRequest
0 голосов
/ 26 сентября 2018

Подумайте о том, чтобы иметь две фабрики менеджера сущностей:

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

Затем я хочу иметь два Бина, в который я бы вставил правильный контекст персистентности:

<bean id="readOnlyManager" class="..MyDatabaseManager">
<bean id="writeManager" class="..MyDatabaseManager">

Боб будет выглядеть как-токак:

public class MyDatabaseManager {

    private javax.persistence.EntityManager em;

    public EntityManager(javax.persistence.EntityManager em) {
        this.em = em;
    }
    ...
}

Это, очевидно, не работает, потому что EntityManager не является бином и не может быть введен таким образом:

No qualifying bean of type 'javax.persistence.EntityManager' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

Как я могу квалифицировать правильный EntityManager в бине?Раньше я использовал аннотацию @PersistenceContext, но ее нельзя использовать, поскольку мне нужно ее внедрить.

Как я могу указать PersistenceContext для такого компонента?

ОБНОВЛЕНИЕ: У меня вопрос, каквведите PersistenceContext с квалификатором через XML, а не с помощью аннотации.

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

persistence.xml (2 единицы персистентности для 2-х различных сущностей-менеджеров, в зависимости от вашего провайдера персистентности, здесь я использую HibernatePersistence)

<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
   <persistence-unit name="pu1">
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
   </persistence-unit>

   <persistence-unit name="pu2">
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
   </persistence-unit>   
</persistence>

Убедитесь, что вы присваиваете блок персистентности менеджеру сущностей с помощью свойства persistenceUnitName

    <bean id="writeEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            <property name="persistenceXmlLocation" value="classpath: of yout persistence xml" />
            <property name="persistenceUnitName" value="pu1" />  
             .....other configuration of em..  
    </bean>

то же самое для других em.

Теперь используйте инъекцию конструктора для MyDatabaseManager, чтобы внедрить EntityManager (используя имя квалификатора, например writeEntityManagerFactory)

<bean id="mdm" class="MyDatabaseManager">
     <constructor-arg ref = "writeEntityManagerFactory"/>
</bean>
0 голосов
/ 01 октября 2018

Предполагая, что вы используете Spring для управления транзакциями, я бы использовал 2 разных менеджера транзакций, а затем в своих сервисах я бы использовал наиболее подходящий менеджер транзакций, такой как:

Раздел конфигурации

@Bean
public LocalContainerEntityManagerFactoryBean writeEntityManagerFactory() {

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    //Your configuration here
    return factory;
}

@Bean(name={"writeTx"})
public PlatformTransactionManager writeTransactionManager() {

    JpaTransactionManager txManager = new JpaTransactionManager();
    txManager.setEntityManagerFactory(writeEntityManagerFactory().getObject());
    return txManager;
}

@Bean
public LocalContainerEntityManagerFactoryBean readEntityManagerFactory() {

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    //Your configuration here
    return factory;
}

@Bean(name={"readTx"})
public PlatformTransactionManager readTransactionManager() {

    JpaTransactionManager txManager = new JpaTransactionManager();
    txManager.setEntityManagerFactory(readEntityManagerFactory().getObject());
    return txManager;
}

Уровень обслуживания

@Transactional(value="readTx")
public List<Object> read(){
    //Your read code here
}

@Transactional(value="writeTx")
public void write(){
    //Your write code here
}

ОБНОВЛЕННЫЙ ОТВЕТ Я неправильно понял вопрос.

В вашемКласс конфигурации, который вы можете определить:

@Bean
    public LocalContainerEntityManagerFactoryBean writeEntityManagerFactory() {

        LocalContainerEntityManagerFactoryBean em  = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource());
        em.setPackagesToScan(new String[] { "models" });
        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        em.setJpaProperties(hibProps());
        em.setPersistenceUnitName("writer");
        return em;
    }
    @Bean
    public LocalContainerEntityManagerFactoryBean readEntityManagerFactory() {

        LocalContainerEntityManagerFactoryBean em  = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource());
        em.setPackagesToScan(new String[] { "models" });
        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        em.setJpaProperties(hibProps());
        em.setPersistenceUnitName("reader");
        return em;
    }   

Пожалуйста, посмотрите PersistenceUnitName значения

Затем вы можете ввести их, выполнив:

@PersistenceContext(unitName="writer")
private EntityManager emWriter;

@PersistenceContext(unitName="reader")
private EntityManager emReader;

Я только что проверил ивсе работало довольно хорошо

Анджело

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...