EclipseLink + Spring Boot Atomikos не сохраняет сущности - PullRequest
0 голосов
/ 01 мая 2019

Моя цель - упаковать несколько ресурсов (несколько баз данных + 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;
}

Как настроить стартер для использования определенного менеджера сущностей / модуля персистентности?

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