Использование контекста сохраняемости USYNCHRONIZED с Hibernate 5.x и Wildlfy

Я пытаюсь перенести приложение, которое использует несинхронизированный контекст сохранения с транзакцией JTA, из спящего режима 4.3.7 в спящий режим 5.0.7, и я обнаружил пару проблем, с которыми не могу справиться. Наш менеджер сущностей введен как

@PersistenceContext(type = PersistenceContextType.EXTENDED, synchronization = SynchronizationType.UNSYNCHRONIZED)
private EntityManager entityManager;

Поэтому я ожидаю, что у меня будет расширенный и несинхронизированный контекст сохранения. Приложение использует функцию UNSYNCHRONIZED, чтобы избежать сброса изменений объектов в базу данных, пока мы этого не захотим. Обычно мы хотим сбрасывать изменения только после операций сохранения/сохранения/удаления, и эти методы вызывают entityManager.joinTransaction();, чтобы явно пометить текущую транзакцию для синхронизации. В некоторой степени это используется для работы в Hibernate 4.3.7, но остановлено в версии 5.

Для версии 5 ребята из Hiberante довольно много переписали, особенно в области обработки транзакций. Насколько я понимаю, спящий режим использует флаг session.autoJoinTransactions для реализации функции UNSYNCHRONIZED. Сессия не будет сброшена (мы используем по умолчанию flushMode.AUTO), если сессия не присоединится к транзакции. Раньше этот флаг устанавливался для новой сессии как

sessionBuilder.autoJoinTransactions( getTransactionType() != PersistenceUnitTransactionType.JTA );

и в спящем режиме 5 (строка EntityManagetImpl 132)

sessionBuilder.autoJoinTransactions( getSynchronizationType() == SynchronizationType.SYNCHRONIZED );

Поскольку мы используем транзакции, управляемые JTA, это работало. Но теперь это не так. Кажется, что выбрать значение autoJoinTransactionflag на основе SynchronizationType — правильно, но есть одна небольшая проблема. ПостоянствоContextTyoe не распространяется на методы EntityFactoryImpl, поэтому диспетчер сущностей всегда создается как синхронизированный. При внедрении entityManager дикий вызов вызывает первый метод, а не второй.

@Override
    public EntityManager createEntityManager(Map map) {
        return internalCreateEntityManager( SynchronizationType.SYNCHRONIZED, map );
    }

    @Override
    public EntityManager createEntityManager(SynchronizationType synchronizationType, Map map) {
        errorIfResourceLocalDueToExplicitSynchronizationType();
        return internalCreateEntityManager( synchronizationType, map );
    }

Итак, мои вопросы: Как внедрить экземпляр диспетчера сущностей с несинхронизированным контекстом сохраняемости? Почему Wildfly игнорирует параметр type = PersistenceContextType.EXTENDED при внедрении диспетчера сущностей? Я что-то пропустил?


person Mikhail Chibel    schedule 09.08.2016    source источник


Ответы (1)


Поскольку тип синхронизации распространяется на внедренный enntiyManager, я понял, что могу использовать EntityManagerFactory для создания entityManger. У фабрики есть метод, принимающий тип синхронизации, поэтому он создаст несинхронизированный контекст.

@PersistenceUnit
private EntityManagerFactory emf;
...
emf.createEntityManager(SynchronizationType.UNSYNCHRONIZED);

Кроме того, я обнаружил, что эта проблема зарегистрирована для WildFly 8.1 https://issues.jboss.org/browse/WFLY-5006

person Mikhail Chibel    schedule 09.08.2016