В существующем состоянии я использую bean-объект в области запросов JSF для выполнения всех моих операций CRUD. Как я уверен, вы, скорее всего, знаете, что Tomcat не обеспечивает управляемую контейнером персистентность, поэтому в моем компоненте CRUD-запроса я использую EnityManagerFactory, чтобы получить сворачивание менеджера enity. Теперь о допустимости моего выбора использовать bean-объект запроса в этой задаче, он, вероятно, открыт для обсуждения (снова), но я пытался поместить его в контекст того, что я прочитал в статьях, которые вы дали мне ссылки в частности, первый и второй. Из того, что я собираю, EclipseLink по умолчанию использует кэш 2-го уровня, в котором хранится кешированный объект. На примерах ExlipseLink - на сайте JPA Caching говорится, что:
Общий кэш существует на время единицы сохраняемости (EntityManagerFactory или сервер)
Теперь это не заставляет мои кэшированные сущности жить в течение доли времени во время вызова, который выполняется к бину запроса CRUD, потому что в тот момент, когда бин уничтожается и с ним EntityManagerFactory, то и кеш также. Также последняя часть вышеприведенного предложения «EntityManagerFactory, или server » вводит меня в заблуждение ... что именно подразумевается под или server в этом контексте и как его контролировать. Если я использую аннотацию @Cache и задаю соответствующее количество атрибута expire, выполнит ли это работу и сохранит ли сущности, хранящиеся в кэше L2 серверов, чем независимо от того, был ли мой EntityManagerFactory уничтожен?
Я понимаю, что нужно уделить много внимания, и у каждого приложения есть свои требования. С моей точки зрения, настройка кэша L2 является, пожалуй, наиболее желательной (если не только, на Tomcat) опцией для оптимизации. Цитата из вашей первой ссылки:
Преимущества кэширования L2:
- исключает доступ к базе данных для уже загруженных объектов
- быстрее для чтения часто используемых неизмененных сущностей
Недостатками кэширования L2 являются:
- потребление памяти для большого количества объектов
- устаревшие данные для обновленных объектов
- параллелизм для записи (исключение оптимистической блокировки или пессимистическая блокировка)
- плохая масштабируемость для часто обновляемых или одновременно обновляемых объектов
Вам следует настроить кэширование L2 для объектов, которые:
- читаю часто
- изменяется редко
- не критично, если устарел
Почти все вышеперечисленные пункты относятся к моему приложению. В основе этого, среди прочего, лежит постоянное и неуклонное чтение сущностей и их отображение на веб-сайте (приложение будет служить порталом для отображения свойств). Кроме того, в приложении создается небольшая корзина для покупок, но продаваемые продукты - это не материальные товары, которые можно приобрести как товар, а услуги. В этом случае устаревшие объекты не являются проблемой, а также, как мне кажется, не являются параллельными, так как продукты (здесь услуги) никогда не будут записаны. Таким образом, объекты будут часто читаться, и они будут изменяться нечасто (а те, которые были изменены, в любом случае не входят в корзину, даже если они изменяются редко) и, следовательно, не критичны, если устарели. Наконец, первые два пункта, кажется, как раз то, что мне нужно, а именно: предотвращение доступа базы данных к уже загруженным объектам и быстрое чтение часто используемых неизмененных объектов. Но есть один недостаток, который меня все еще беспокоит: потребление памяти для большого количества объектов. Разве это не похоже на мою первоначальную проблему?
Насколько я понимаю, есть два варианта, только один из которых применим к моей ситуации:
Чтобы иметь возможность делегировать работу с более длительным кэшированием на уровень персистентности, чем у меня должен быть доступ к PersistenceContext, создать бин области действия сеанса и установить PersistenceContextType.EXTENDED. (этот параметр не относится ко мне, нет доступа к PersistenceContext).
Сконфигурируйте аннотацию L2 @Cache для сущностей или, как в варианте 1 выше, создайте сессионный компонент с областью действия, который будет обрабатывать долгосрочное кэширование. Но разве они не возвращаются к моей первоначальной проблеме?
Мне бы очень хотелось услышать ваше мнение и посмотреть, что, по вашему мнению, может быть разумным способом подойти к этому, или, возможно, как вы подходили к нему в своих предыдущих проектах. О, и еще одна вещь, просто чтобы подтвердить ... при аннотировании сущности с помощью @Cache все связанные сущности будут кэшироваться вместе, поэтому мне не нужно аннотировать их все?
Снова все комментарии и указатели очень ценятся.
Спасибо за ваш ответ. Когда вы говорите
«В Tomcat лучше всего иметь статический менеджер, который будет удерживать EntityManagerFactory на время работы сервера».
Означает ли это, что я могу, например, объявить и инициализировать статическое поле EntityManagerFactory в области приложения, которая впоследствии будет использоваться всеми компонентами в течение всего жизненного цикла приложения?