JPA: всегда ли EntityManager.find() возвращает одну и ту же ссылку на объект для одного и того же ключа?

У меня есть тест интеграции DAO, в котором я использую общий EntityManager (через Spring, используя SharedEntityManagerCreator). Класс теста помечен как @Transactional, как и тестируемый метод DAO.

И в тестовом классе, и в DAO я получаю сущность User следующим образом:

User user = em.find(User.class, "test");

В настройке моего теста я изменил пользовательский объект, но я не видел изменений в DAO, когда тест запустился. Оказалось, что две ссылки не относятся к одному и тому же объекту; Я доказал это в моем тестовом классе, используя:

System.out.println("User objects equal = " + (user == dao.getUser()));

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

Спасибо!

Java 1.6u22, Toplink Essentials 2.0.1, весна 2.5.6

2 ответа

Решение

find() возвращает тот же экземпляр внутри контекста персистентности.

В случае общего EntityManager (контекст сохраняемости в управляемой контейнером транзакции, в терминах спецификации JPA) жизненный цикл контекста постоянства связан с транзакцией, поэтому find() возвращает тот же экземпляр при вызове из той же транзакции. Я предполагаю, что в вашем случае настройка вашего теста не происходит в той же транзакции, что и метод теста, поэтому find() производит разные экземпляры.

Нет. В любом случае вы должны полагаться на объект РАВЕНСТВО вместо IDENTITY. Переопределите метод equals.

Другие вопросы по тегам