Моя цель - упаковать несколько ресурсов (несколько баз данных + JMS) в одну глобальную транзакцию. Но я сталкиваюсь с проблемой уже по простому сценарию.
Я использую org.springframework.boot:spring-boot-starter-jta-atomikos:2.1.4.RELEASE
и единицу постоянства EclipseLink:
@Configuration
public class EclipseLinkJpaConfigDomain {
private static final String PERSISTENCE_UNIT = "mydomain";
@Bean(PERSISTENCE_UNIT)
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, DataSource dataSource) {
return builder.dataSource(dataSource)
.persistenceUnit(PERSISTENCE_UNIT)
.jta(true)
.build();
}
@Bean
PersistenceUnitManager persistenceUnitManager(DataSource dataSource) {
DefaultPersistenceUnitManager pum = new DefaultPersistenceUnitManager();
pum.setPersistenceXmlLocations("classpath*:META-INF/persistence-eclipselink-h2.xml");
pum.setDefaultJtaDataSource(dataSource);
pum.afterPropertiesSet();
return pum;
}
}
Единица постоянства устанавливается следующим образом:
// META-INF/persistence-eclipselink-h2.xml
<?xml version="1.0" encoding="UTF-8"?>
<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 https://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="mydomain" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<mapping-file>META-INF/eclipselink-orm-mydomain.xml</mapping-file>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<shared-cache-mode>NONE</shared-cache-mode>
<validation-mode>AUTO</validation-mode>
<properties>
<property name="eclipselink.weaving" value="false"/>
<property name="eclipselink.logging.parameters" value="true"/>
<property name="eclipselink.logging.level" value="WARNING"/>
<property name="eclipselink.ddl-generation" value="none"/>
<property name="eclipselink.target-database" value="org.eclipse.persistence.platform.database.H2Platform"/>
<property name="eclipselink.jpa.uppercase-column-names" value="true"/>
<property name="eclipselink.cache.shared.default" value="false"/>
<property name="javax.persistence.sharedCache.mode" value="NONE"/>
</properties>
<class>com.example.mydomain.MyEntity</class>
</persistence-unit>
</persistence>
// META-INF/eclipselink-orm-mydomain.xml
<?xml version="1.0"?>
<entity-mappings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/orm http://www.eclipse.org/eclipselink/xsds/eclipselink_orm_2_5.xsd">
<persistence-unit-metadata>
<persistence-unit-defaults>
<schema>mydomain</schema>
</persistence-unit-defaults>
</persistence-unit-metadata>
</entity-mappings>
Ниже приведена конфигурация EclipseLink:
@Configuration
public class EclipselinkJpaConfiguration extends JpaBaseConfiguration {
@Override
protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
return new EclipseLinkJpaVendorAdapter();
}
}
Я использую хранилище для сохранения сущностей:
@Repository
public class MyRepository {
@PersistenceContext(unitName = "mydomain")
protected EntityManager em;
public List<MyEntity> listEntities() {
return em.createQuery("select me from MyEntity me", MyEntity.class).getResultList();
}
@Transactional
public void saveEntity(MyEntity entity) {
em.persist(entity);
}
}
К сожалению, это не работает - после вызова saveEntity
возвращает listEntities
пустой список.
Когда я определяю пользовательский менеджер транзакций, все работает нормально, но это должно быть обеспечено стартером из коробки (если я правильно понимаю).
@Bean
public PlatformTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean emf) {
JpaTransactionManager tm = new JpaTransactionManager();
tm.setEntityManagerFactory(emf.getObject());
tm.setPersistenceUnitName("mydomain");
tm.afterPropertiesSet();
return tm;
}
Как настроить стартер для использования определенного менеджера сущностей / модуля персистентности?