2013-11-13 5 views
2

Я использую Hibernate как реализацию JPA. В моем приложении vaadin EntityManager является областью действия запроса (чтобы избежать неконтролируемого фиксации накопленных изменений). Я храню отдельный элемент в сеансе и повторно подключаю его каждый раз, когда это необходимо в запросе (один раз за запрос, я проверяю это, используя em.contains()). Entity ссылается на другой объект, который ссылается на другой, поэтому в конце я имею трехуровневый каскадный диаграмму дерева с указанным объектом с сессией в виде корня.EntityManager.merge (x) вызывает запрос «select» к DB

Это работает отлично, пока я не большое совершенно новое дерево с совершенно новыми узлами (всего более 5000 наименований) - Hibernate пытается найти каждый новый узел по слиянию (я могу видеть свои попытки в моих журналах - много select комиссионки неиспользуемые идентификаторы). Это ошибка, или я просто злоупотребляю JPA?

Update

Я не использую @Version поле.

Update *

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

+0

У вас есть '@ Version'fields? Можете ли вы показать соответствующие части ваших объектов (поля идентификатора и отношения между ними)? –

+0

@Andrei Я не использую поля '@ Version' (как я думал, это необходимо только при работе с блокировкой записей). Есть ли какие-либо последствия или правила для использования поля '@ Version'? (обновленное описание) –

+0

Никаких специальных правил (помимо типа), но последствия могут быть (в зависимости от реализации), поскольку Оптимистическая блокировка означает сравнение поля '@ Version' с текущими данными в БД (что может означать выбор) , Вы ничего не публиковали из своего кода. –

ответ

2

Я думаю, вы должны использовать entityManager.persist() для совершенно нового дерева вместо entityManager.merge(), чтобы избежать новых выборов. merge() может использоваться как для новых, так и для постоянных объектов, а спящий режим должен решить, что делать (вставки или обновления SQL), и для этого ему нужны эти select.

+0

Хорошо, я вижу вашу мысль. Но есть два следующих момента: 1) У меня было плохое время с помощью 'Eclipselink' и' persist() '- on' persist() 'Eclipselink пытается сохранить все дерево объектов независимо от каскадных настроек. Таким образом, на основе этого поведения было написано много кода, и когда проблема была замечена ('merge()' учитывает типы каскадов), было слишком поздно менять код. Я хочу избежать этих ситуаций в будущем (независимо от поставщика JPA). 2) Если я загружаю корневой объект (а затем добавляю 5000 детей), 'persist()' больше не используется. –

+0

1. Я сомневаюсь, что EclipseLink (или любые другие поставщики JPA) игнорируют каскадные настройки persist(), но это заслуживает (или заслуживает, когда у вас возникла проблема) целый отдельный вопрос. 2. Конечно, вы не можете использовать persist для уже существующего объекта, но ваш код должен знать лучше, когда вызывать persist() и merge(), поскольку они являются разными сценариями. –

+0

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

Смежные вопросы