powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / EclipseLink + Spring @Transactional
5 сообщений из 5, страница 1 из 1
EclipseLink + Spring @Transactional
    #39253540
SergWF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем доброго дня.

Возникла нужда в имеющемся Spring-boot приложении мигировать от Hibernate на EclipseLink.
В процессе миграции обнаружилась странная особенность. Если метод помечен как @org.springframework.transaction.annotation.Transactional, то ВНУТРИ МЕТОДА при сохранении нового entity репозиторий возвращает неизмененный объект (entity.id == null).
Если на методе нет аннотации @Transactional и/или транзакция стартует "мануально", то все ок, entity.id содержит значение первичного ключа.
Такое поведение началось только после миграции на EclipseLink.

Тут ошибка:
Код: java
1.
2.
3.
4.
5.
6.
    
    @Transactional
    public Employee createEmployee(){
        Employee employee = employeeRepository.save(new Employee("vasya", "pupkin"));
        processEmployee(employee); //employee.id == null
    }


транзакция запускается явно, все Ок:
Код: java
1.
2.
3.
4.
5.
6.
    public Employee createEmployee(){
       TransactionStatus status = transactionManager.getTransaction(createDefinition("trCreateEmployee"));
            Employee employee = employeeRepository.save(new Employee("vasya", "pupkin"));
            processEmployee(employee); //employee.id==1234
      transactionManager.commit(transaction);
    }



Нет @Transactional, тоже все Ок:
Код: java
1.
2.
3.
4.
    public Employee createEmployee(){
            Employee employee = employeeRepository.save(new Employee("vasya", "pupkin"));
            processEmployee(employee); //employee.id==1234
    }




Конфигурация:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
@Configuration
@EnableJpaRepositories
@EnableJpaAuditing
@EntityScan
@PropertySource("classpath:storage.properties")
@ComponentScan
@EnableAutoConfiguration
public class StorageConfig extends JpaBaseConfiguration {
    private static Logger logger = LoggerFactory.getLogger(StorageConfig.class);

    @Autowired
    private JpaProperties jpaProperties;

    @Override
    protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
        final EclipseLinkJpaDialect customDialect = new EclipseLinkJpaDialect() {
            @Override
            public ConnectionHandle getJdbcConnection(EntityManager entityManager, boolean readOnly) throws
                    PersistenceException, SQLException {
                // Hides: return super.getJdbcConnection(entityManager, readOnly);
                return null;
            }
        };

        customDialect.setLazyDatabaseTransaction(false);

        return new EclipseLinkJpaVendorAdapter(){
            @Override
            public EclipseLinkJpaDialect getJpaDialect() {
                return customDialect;
            }
        };
    }

    @Override
    protected Map<String, Object> getVendorProperties() {
        Map<String, Object> vendorProperties = new LinkedHashMap<>();
        vendorProperties.putAll(this.jpaProperties.getProperties());
        vendorProperties.put(PersistenceUnitProperties.BATCH_WRITING, BatchWriting.JDBC);
        vendorProperties.put(PersistenceUnitProperties.WEAVING, "static");
        vendorProperties.put(PersistenceUnitProperties.PERSISTENCE_CONTEXT_FLUSH_MODE, "auto");
        vendorProperties.put(PersistenceUnitProperties.TARGET_DATABASE, TargetDatabase.PostgreSQL);
        return vendorProperties;
    }

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
        return new JpaTransactionManager(emf);
    }
}



Репозиторий:
Код: java
1.
2.
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}


Как можно исправить поведение @Transactional?
...
Рейтинг: 0 / 0
EclipseLink + Spring @Transactional
    #39253568
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В принципе, поведение объяснимое. Интересно было бы разобраться почему в Hibernate работало.
В ручном управлении транзакцией есть подозрение, что эта транзакция просто не распространяется на репозиторий, и получается то же самое что и при отсутствии @Transactional. То есть в этих двух случаях репозиторий делает коммит.

В случае же с открытой транзакцией ни flush ни коммит не происходит. Возможно, в Hibernate на этот случай есть костыль, чтобы гарантировать наличие id, он такие делает flush.
...
Рейтинг: 0 / 0
EclipseLink + Spring @Transactional
    #39253571
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SergWF,

Вот тут ещё приведены настройки EclipseLink по делу
http://stackoverflow.com/a/19846340
Есть смысл попробовать.
...
Рейтинг: 0 / 0
EclipseLink + Spring @Transactional
    #39253590
SergWF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Для получения Id нет необходимости коммитить данные. Но записать данные в БД JPA вполне может. Что Hibernate и делает. Похоже EclipseLink персистит объекты как-то иначе. Надеюсь, что существует возможность изменить это поведение конфигурацией.
...
Рейтинг: 0 / 0
EclipseLink + Spring @Transactional
    #39253643
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SergWFДля получения Id нет необходимости коммитить данные.
Речь не о коммите. Для коммита требуется flush. И для генерации Id требуется flush. Поэтому там где был коммит, на уровне репозитория, там был и flush. А там где не было коммита, не было и flush и id null-овый.
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / EclipseLink + Spring @Transactional
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]