Откат Atomikos не очищает контекст постоянства JPA? - PullRequest
0 голосов
/ 14 июня 2010

У меня есть приложение Spring / JPA / Hibernate, и я пытаюсь заставить его пройти мои интеграционные тесты Junit для H2 и MySQL. В настоящее время я использую Atomikos для транзакций и C3P0 для пула соединений.

Несмотря на все мои усилия, моя интеграция с DAO завершила один из тестов с org.hibernate.NonUniqueObjectException. В неудачном тесте я создаю объект с оператором «new», устанавливаю идентификатор и вызываю для него постоянный вызов.

@Test
@Transactional
public void save_UserTestDataNewObject_RecordSetOneLarger() {
    int expectedNumberRecords = 4;
    User newUser = createNewUser();

    dao.persist(newUser);   
    List<User> allUsers = dao.findAll(0, 1000);

    assertEquals(expectedNumberRecords, allUsers.size());
}

В предыдущем методе test я делаю то же самое (createNewUser () - вспомогательный метод, который создает объект с одинаковым идентификатором каждый раз). Я уверен, что причиной является создание и сохранение второго объекта с тем же идентификатором, но каждый метод тестирования находится в собственной транзакции, а созданный мной объект привязан к закрытой переменной метода метода. Я даже вижу в журналах, что Spring Test и Atomikos откатывают транзакцию, связанную с каждым методом тестирования.

Я бы подумал, что откат также очистил бы контекст постоянства. Надеюсь, я добавил вызов dao.clear () в начале ошибочного метода тестирования, и проблема ушла !! Таким образом, откат не очищает контекст постоянства ??? Если нет, то кто это делает?

Моя конфигурация EntityManagerFactory выглядит следующим образом:

<bean id="myappTestLocalEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="myapp-core" />
        <property name="persistenceUnitPostProcessors">
            <bean class="com.myapp.core.persist.util.JtaPersistenceUnitPostProcessor">
                <property name="jtaDataSource" ref="myappPersistTestJdbcDataSource" />
            </bean>
        </property>

        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="true" />
                <property name="database" value="$DS{hibernate.database}" />
                <property name="databasePlatform" value="$DS{hibernate.dialect}" />
            </bean>
        </property>

        <property name="jpaProperties">
            <props>
                <prop key="hibernate.transaction.factory_class">com.atomikos.icatch.jta.hibernate3.AtomikosJTATransactionFactory</prop>
                <prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup</prop>
                <prop key="hibernate.connection.autocommit">false</prop>
                <prop key="hibernate.format_sql">true"</prop>
                <prop key="hibernate.use_sql_comments">true</prop>
    </property>
</bean>

Ответы [ 2 ]

1 голос
/ 15 июня 2010

Проблема в этом случае заключалась в том, что у меня был управляемый приложением менеджер расширенных транзакций, внедряемый в мои DAO.Причину этого можно найти здесь:

Проблема с созданием JPA EntityMananger в контексте Spring

Как только я исправил свой менеджер сущностей - все заработало.

1 голос
/ 14 июня 2010

Это странно.Из спецификации JPA:

3.3.2 Откат транзакции

Как для контекста с расширенной областью транзакции, так и для расширенного персистентного контекста, откат транзакции вызывает все существующие ранее управляемые экземплярыи удалены экземпляры, чтобы стать отделенным.Состояние экземпляров будет состоянием экземпляров в тот момент, когда транзакция была откатана.Откат транзакции обычно приводит к тому, что постоянный контекст находится в несогласованном состоянии в момент отката.В частности, состояние атрибутов версии и сгенерированного состояния (например, сгенерированных первичных ключей) может быть несовместимым.Экземпляры, которые ранее управлялись контекстом постоянства (включая новые экземпляры, которые были сделаны постоянными в этой транзакции), могут поэтому не использоваться повторно таким же образом, как другие отсоединенные объекты - например, они могут потерпеть неудачу при передаче в операцию слияния.

Способ, которым я прочитал вышеизложенный раздел, заключается в том, что при откате транзакции JPA должен очистить свой контекст постоянства.

...