Hibernate / Spring: getHibernateTemplate (). Save (...) зависает / зависает - PullRequest
4 голосов
/ 08 января 2011

Я использую Hibernate и Spring с шаблоном DAO (все зависимости Hibernate в классе * DAO.java).У меня есть девять модульных тестов (JUnit), которые создают некоторые бизнес-объекты, сохраняют их и выполняют над ними операции;объекты находятся в хэше (поэтому я все время использую одни и те же объекты).

Мой метод установки JUnit вызывает мой метод DAO.deleteAllObjects(), который вызывает getSession().createSQLQuery("DELETE FROM <tablename>").executeUpdate() для моей таблицы бизнес-объектов (только один).

Один из моих юнит-тестов (# 8/9) зависает.Я предположил, что это была тупиковая ситуация с базой данных, потому что в файле журнала Hibernate последний раз показывался мой оператор удаления.Однако отладка показала, что просто HibernateTemplate.save(someObject) зависает.(Eclipse показывает, что он зависает на HibernateTemplate.save(Object), строка 694 .)

Также интересно отметить, что выполнение этого теста само по себе (не в наборе из 9 тестов) невызвать какие-либо проблемы.

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

Кроме того, я использую аннотации @Entity, если это имеет значение.

Редактировать: Я удалил повторное использование своих бизнес-объектов (используйте уникальные объекты в каждом методе) - ничего не изменилось (все еще зависает).

Редактировать: Это начало капатьи в другие тесты (нельзя запустить более одного тестового класса, не замерзнув)

Редактировать: Работает разбиение тестов на замораживание на два класса.Я собираюсь сделать это на данный момент, так же позорно и нечисто, как если бы два или более тестовых класса проводили модульное тестирование одного и того же класса бизнес-объекта.

Конфигурация транзакции:

    <bean id="txManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <tx:advice id="txAdvice" transaction-manager="txManager">
        <!-- the transactional semantics... -->
        <tx:attributes>
            <!-- all methods starting with 'get' are read-only -->
            <tx:method name="get*" read-only="true" />
            <tx:method name="find*" read-only="true" />
            <!-- other methods use the default transaction settings (see below) -->
            <tx:method name="*" />
        </tx:attributes>
    </tx:advice>

    <!-- my bean which is exhibiting the hanging behavior -->
    <aop:config>
    <aop:pointcut id="beanNameHere"
        expression="execution(* com.blah.blah.IMyDAO.*(..))" />
    <aop:advisor advice-ref="txAdvice" pointcut-ref="beanNameHere" />
</aop:config>

Ответы [ 2 ]

1 голос
/ 09 января 2011

Несколько вещей для проверки:

  • правильное управление транзакциями - кажется, что в вашей конфигурации у вас есть транзакции через вашу DAO. Как правило, желательно, чтобы транзакции проходили вокруг уровня обслуживания, а не DAO. Но в любом случае - убедитесь, что у вас есть транзакция вокруг дао, используемая тестом. Или сделайте тест @Transactional (при использовании пружинного бегуна)

  • изменить порог ведения журнала на info для источника данных (возможно, c3p0?). Он сообщает о тупиках.

  • смотреть журналы базы данных на наличие взаимоблокировок (если есть такая опция)

1 голос
/ 08 января 2011

Когда происходит зависание, прервите приложение, найдите основной поток и перехватите трассировку стека.Пролистайте, пока не найдете точно, какой запрос к БД, который блокирует БД.

Вы упомянули, что тест выполняется самостоятельно, но запуск полного пакета вызывает проблемы.Если это так, то я бы предположил, что в одном из предыдущих тестов транзакция по-прежнему открыта и имеются блокировки в некоторых строках, к которым пытается обратиться блокирующий тест.

Работают ли ваши тесты одновременно?Если это так, прекратите это делать, поскольку они могут мешать друг другу.

Включите параметр hibernate.show_sql, чтобы вы могли видеть в консоли весь генерируемый SQL.

В тот момент, когда происходит зависаниеВы можете узнать, какие строки заблокированы в БД.например, в SQLServer вы можете запустить sp_lock, чтобы увидеть это, и sp_who, чтобы увидеть, какие идентификаторы процесса SQL блокируют другой.

...