JPA/EclipseLink: отключить каскад для определенных операций слияния?

Я использую EclipseLink 2.3.3. с моделью данных с около 100 объектов. У меня есть класс Java, сопоставленный каждой таблице базы данных с помощью аннотаций.

У меня есть два варианта использования для реализации. Во-первых, в систему входит новая запись, которая охватывает около 60-75 таблиц. В этом случае я хочу объединить и сохранить каскад, чтобы я мог просто объединить объект верхнего уровня и иметь этот каскад для всех связанных объектов.

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

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

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

Поэтому мне интересно, есть ли где-нибудь лучший ответ, который я пропускаю? Спасибо за любую информацию.

1 ответ

Я не уверен в том, какой уровень контроля вы используете, особенно в том случае, если вы упомянули, что хотите вставить отдельные объекты. Судя по всему, каскадное слияние - это именно то, что вам нужно для дерева объектов Entity в первом случае для использования с EntityManager.merge. Слияние, вызванное для объекта, проверит, является ли оно новым или нет, и обновит или вставит в случае необходимости. Маркировка отношений как каскадное слияние позволит находить новые объекты и вставлять их.

Во втором случае, хотя вы хотите обрабатывать отдельные вставки, почему бы не исключить опцию cascade persist для отображений и просто вызвать EntityManager.persist для объектов, которые вы хотите вставить? Persist не будет каскадным, поэтому будет вставлен только объект, для которого вы вызываете em.persist. Отношения будут использоваться только для установки значений внешнего ключа - хотя вы можете оставить их обнуленными и установить их позже как часть более крупных вызовов слияния. Обе стороны двунаправленных отношений должны поддерживаться, и если другая сторона существует и не объединяется, изменения ее отношений не сохраняются.

Если это не то, что вам нужно, EclipseLink имеет встроенный API на UnitOfWork (EntityManager по существу оборачивает UnitOfWork для транзакционной работы), который позволяет вам указать политику слияния. См. MergeClone, deepMergeClone и shallowMergeClone в UnitOfWork, которые по существу используют CASCADE_ALL_PARTS, CASCADE_PRIVATE_PARTS и NO_CASCADE соответственно в качестве политик слияния, в то время как JPA объединяет использование CASCADE_BY_MAPPING.

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