@gsaw

Почему могут не сохраняться сущности в базе данных?

У меня задача, читать в одной базе данных (db2), а писать в другую (oracle).

spring boot jpa, hibernate

Я сконфигурировал у себя два Datasource, два EntityManagerFactory, два PlatformTransactionManager. Под каждую базу.

У меня так же под вторую базу данных есть набор Entity классов и к каждому у меня есть свой Repository extends JpaRepository.

Собственно сетап работает. Так как приложение наверняка может читать в базе - источнике данных и апдейтить там данные jdbcTemplate компонентой. В другой базе - куда надо писать, приложение тоже может читать. Я в трейсах вижу запросы к базе (к примеру что бы посчитать количество записей в табличке) метода findById репозитория.

Но потом начинается какая то фигня, при попытке писать через репозитории. Вызвается метод save(entity) я в логе hibernate вижу, что сущность добавлена в очередь.
22-01-21 Fr 20:15:16.830 DEBUG  [actSaveEventListener] : Generated identifier: component[]{}, using strategy: org.hibernate.id.CompositeNestedGeneratedValueGenerator
22-01-21 Fr 20:15:16.830 TRACE  [actSaveEventListener] : Saving [com.batch.vamos2dwh.writer.persistence.dwh.model.StF...
22-01-21 Fr 20:15:16.830 TRACE  [ActionQueue         ] : Adding an EntityInsertAction for [com.batch.vamos2dwh.writer.persistence.dwh.model.StF...] object
22-01-21 Fr 20:15:16.830 TRACE  [ActionQueue         ] : Adding insert with no non-nullable, transient entities: [EntityInsertAction[com.batch.vamos2dwh.writer.persistence.dwh.model.StF...]
22-01-21 Fr 20:15:16.830 TRACE  [ActionQueue         ] : Adding resolved non-early insert action.


Но почему то сущность в итоге не пишется в базу данных. Я не вижу даже insert-ов в логе.

Я думаю у меня какая то фигня с транзакциями.

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

@Bean(name = "chainedTransactionManager")
    public ChainedTransactionManager transactionManager(@Qualifier("dwhTransactionManager") PlatformTransactionManager ds1,
                                                    @Qualifier("vamosTransactionManager") PlatformTransactionManager ds2) {
         return new ChainedTransactionManager(ds1, ds2);
    }


И использую его в самой первой точке входа компоненты, которая потом все это делает.

@Transactional(value="chainedTransactionManager", propagation = Propagation.REQUIRES_NEW)
    public int processSCFZ() {


Больше у меня transactional нигде нету, и метод processSCFZ вызвается из другогой компоненты. Связанны по @Autowired, то -есть транзакция должна создаваться.

Я почему грешу на транзакции, потому что я вижу, в логе для каждого save

getting transaction for blablaEntityRepository.save


Это вроде не нормально.

Почему такое может происходить? Как то можно включить трассировку этих транзакций, что бы понять, почему она не создается. А то уже все отмечают пятницу, а я так и не смог записать в базу. Причем когда все это читало данные не из другой базы данных, а из MQ, все работало и писало в базу как надо. Сломалось после того как добавил вторую базу источником.

Вот конфигурация целевой базы, которая не хочет писать данные. Другая сконфигурирована аналогично, только другой префикс

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        basePackages = "com.batch.vamos2dwh.writer.persistence.dwh.repository",
        entityManagerFactoryRef = "dwhEntityManagerFactory",
        transactionManagerRef = "dwhTransactionManager")
public class DwhDatasourceConfiguration {
    @Value("${dwh.jpa.properties.hibernate.dialect}")
    private String hibernateDialect;

    @Bean(name = "dwhDatasource")
    @ConfigurationProperties(prefix = "dwh.datasource")
    @Primary
    public DataSource dwhDatasource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "dwhTransactionManager")
    @Primary
    public PlatformTransactionManager dwhTransactionManager(@Qualifier("dwhDatasource") DataSource ds) {
        return new DataSourceTransactionManager(ds);
    }

    @Bean(name = "dwhJdbc")
    public JdbcTemplate vamosJdbc(@Qualifier("dwhDatasource") DataSource ds) {
        return new JdbcTemplate(ds);
    }

    @Bean(name = "dwhEntityManagerFactory")
    @Primary
    public LocalContainerEntityManagerFactoryBean dwhEntityManagerFactory(
            EntityManagerFactoryBuilder entityManagerFactoryBuilder,
            @Qualifier("dwhDatasource") DataSource dwhDatasource) {

        HashMap<String, Object> props = new HashMap<>();
        props.put("hibernate.dialect", hibernateDialect);

        return entityManagerFactoryBuilder
                .dataSource(dwhDatasource)
                .properties(props)
                .packages("com.batch.vamos2dwh.writer.persistence.dwh")
                .persistenceUnit("dwhPersistence")
                .build();
    }
}
  • Вопрос задан
  • 53 просмотра
Решения вопроса 1
@gsaw Автор вопроса
Моя ошибка была

@Bean(name = "dwhTransactionManager")
    @Primary
    public PlatformTransactionManager dwhTransactionManager(@Qualifier("dwhDatasource") DataSource ds) {
        return new DataSourceTransactionManager(ds);
    }


Вместо DataSourceTransactionManager надо было JpaTransactionManager использовать. Получалось, что JpaRepository не работали как надо. Данные запрашивать можно было, а запись в нирвану уходила. Поменял на JpaTransactionManager и все заработало.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы