Сущности JPA в кластере серверов

Мы начинаем разработку нового веб-приложения с использованием JSF (MyFaces на TomEE) и JPA (Eclipselink).

Чтобы ускорить разработку, мы планируем НЕ разрабатывать слой DTO, в основном потому, что он нам не нужен. Следуя советам экспертов JSF и Java EE, таких как Бауке Шольц Как использовать DTO в JSF + Spring + Hibernate и Адам Бьен Насколько злы объекты передачи данных, мы будем использовать объекты JPA непосредственно на уровне представления. Тем не менее, это приложение должно работать в кластере серверов с липкой сессией. Когда сервер отключается на техническое обслуживание или исключается из кластера для развертывания приложений, пользовательские сеансы этого сервера должны обслуживаться другими серверами без потери сеанса.

Проблема, с которой мы сталкиваемся, заключается в том, что объекты JPA, которые сохраняются в сеансе (например, в bean-компоненте @ViewScoped), не «полностью» реплицируются на других серверах. На самом деле атрибуты коллекции сущностей JPA, которые используют отложенную загрузку, не могут использоваться на других серверах. При доступе к атрибуту коллекции (@OneToMany, использующему отложенную загрузку) на сервере с репликой сеанса исключение

org.eclipse.persistence.exceptions.ValidationException 
Exception Description: An attempt was made to traverse a relationship 
using indirection that had a null Session.  
This often occurs when an entity with an uninstantiated LAZY 
relationship is serialized and that relationship is traversed 
after serialization. 
To avoid this issue, instantiate the LAZY relationship 
prior to serialization

брошен.

Я знаю, что EntityManager не сериализуем, и объекты JPA полностью отсоединяются при сериализации во время миграции сеанса, см. Блог Струберга.

Итак, вопрос в том, есть ли способ поддерживать объекты JPA согласованным образом в кластере серверов без использования загрузки EAGER?

У тебя кеш включен?

Sorin Penteleiciuc 20.02.2019 12:48

Может быть, что-то вроде stackoverflow.com/questions/7058843/… помогает (вопрос о кеше, как в предыдущем комментарии) и использовать его реплицированным способом

Kukeltje 20.02.2019 12:48

Вы пытались проверить, отделена ли сущность + объединена с этой сущностью, прежде чем обращаться к коллекции?

tandraschko 20.02.2019 13:10

@SorinPenteleiciuc да кеш включен

Alexcat 20.02.2019 13:56

@tandraschko Да, объекты явно отсоединяются, когда сеансы переносятся на сервер-реплику. Как переподключить их прозрачным образом с точки зрения приложения?

Alexcat 20.02.2019 14:03

@Kukeltje спасибо, но я думаю, что проблема не связана с кешем. Проблема в том, что сущности на сервере-реплике отсоединены. Так, например, при доступе к коллекциям OneToMany возникает исключение.

Alexcat 20.02.2019 14:08

Если вы не используете их в сеансе, а повторно используете из кеша, это не проблема iirc. И сущности, помещенные в сеанс, в любом случае отсоединяются от диспетчера сущностей, даже на том же сервере (если вы не используете расширенный контекст сохранения, который сам по себе является «опасным» iirc).

Kukeltje 20.02.2019 14:45

@Kukeltje Я ничего не добавляю в сеанс, это JSF использует сеанс для сохранения области, например ViewScoped. Таким образом, если сервер выходит из строя, пользовательский сеанс перенаправляется на резервный сервер, но все сущности, объявленные на странице ViewScoped, отсоединяются. Я не использую расширенный контекст сохраняемости, доступ к коллекциям через ленивую загрузку в отсоединенных объектах разрешен, см. objectdb.com/issue/326

Alexcat 20.02.2019 15:10

Я всегда использую EntityManager#merge — такая же проблема возникает, когда вы используете ViewScope с объектами + RequestScoped EM.

tandraschko 20.02.2019 21:05
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
9
483
1

Ответы 1

Вы можете настроить кеш только для некоторых сущностей (те, которые меняются очень редко)

<?xml version = "1.0" encoding = "UTF-8"?>
<persistence xmlns = "http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation = "http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
             version = "2.1">

    <persistence-unit name = "name" transaction-type = "JTA">
        <!-- disable shared cache because we are in multi instance environment -->
        <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
        <validation-mode>CALLBACK</validation-mode>

        <properties> 
            <!-- disable object caching because we are in multi instance environment -->
            <property name = "eclipselink.cache.shared.default" value = "true"/>
            <property name = "javax.persistence.sharedCache.mode" value = "ENABLE_SELECTIVE"/>
            </properties>
    </persistence-unit>

</persistence>

Вы также можете увидеть здесь, как это сделать в общей среде. https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching/Query_Cache

Это не проблема кэша. Если сервер выходит из строя, пользовательский сеанс перенаправляется на резервный сервер, но все сущности, объявленные на странице ViewScoped, отсоединяются. Например, если я получаю доступ к ленивой коллекции @OneToMany на сервере резервного копирования, возникает исключение. Этого не происходит на сервере, который сначала загружается как сущности.

Alexcat 21.02.2019 09:51

@Alexcat: (Http) Кэш сеанса/отработка отказа! = Кэш jpa/отработка отказа

Kukeltje 11.07.2019 12:41

@Kukeltje да, я знаю. Итак, вы верите, что исключение, о котором я сообщил выше org.eclipse.persistence.exceptions.ValidationException, связано с кешем jpa? В описании исключения ясно указано, что это происходит, когда сущность сериализуется, и во время миграции (Http)Session объекты сериализуются!

Alexcat 11.07.2019 14:40

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