Реліз Spring WebFlow 2.0
Spring WebFlow використовується як доповнення до вже існуючих веб-фреймворків (наприклад, Spring MVC, JSF).
Даний фреймворк дозволяє представити веб аплікацію у вигляді flow'ів, кожен з яких містить набір станів та переходів між станами. Кожний такий flow можна уявити собі вигляді діаграми станів UML. Практично, діаграма станів використовується для того, щоб графічно змоделювати або показати набір станів в межах flow. Це є прекрасний спосіб вирішення навігації та роботи із станами в межах веб аплікації.
"Implementation Patterns" by Kent Beck

В дорозі до Львову і назад я все-таки знайшов час, щоб дочитати до кінця книгу Кента Бека (Kent Beck) "Implementation Patterns". Дана книжка є таким собі збірником паттернів по написанню коду. В дечому вона перехрещується із всім відомою книгою "Code Complete". Книга орієнтована на Java програмістів; приклади в книзі приводяться на Java, розглядається навіть Collection API, виникає навіть деколи відчуття, що декотрі шаблони підточені під Java.
Взагалі, книжка має досить просту і зручну структуру. Ця стуктура позволяє вам перечитати книжку від корочки до корочки, а також користуватися як каталогом шаблонів.
В ній можна знайти такі розділи:
- Theory of Programming розказує про основні цінності та принципи створюваних програм. Виділяється 3 цінності ПЗ, що слід досягати – це взаємодія, простота та розширюваність.
- Class - біля 17 шаблонів (типів) класів, що зустрічатимуться програмісту при розробці програм. Цей розділ описує, які класи можуть бути, як слід виділяти та створювати класи та інтерфейси.
- State. Такі шаблони, як
Direct Access, Indirect Access, Variable, Field, Var Args, Parameterта ще коло 20 патернів. Ці шаблони описують стан (дані) класу, як правильно організовувати стан, як правильно оформлювати доступ, ініціалізацію тощо. - Behavior. Ще 14 шаблонів повязаних із поведінкою. У доповненні до опису шаблонів пов'язаних із станом класів, подаються також шаблони поведінки, роботи із даними. Розглядаються потоки виконання програм і шаблони повідомлень, якими обмінюються класи.
- Methods. Ну і як без методів. Цій частині виділяється окремий розділ, який описує такі шаблони, як
Factory Method, Helper Method, Query Method, Method Object, Creation, Composed Method etc.Я в свою чергу звернув увагу, наMethod Object: перечитуючи його, я згадував усі ті рази коли він міг мені знадобитися. - Collections. Автор звертає нашу увагу на бібліотеку колекцій, що існує в Java SE. Доречі, мене зацікавили графіки-порівняння залежності часу виконання операцій від кількості елементів для різних реалізацій контейнерів.
- Evolving Frameworks. Окремий розділ, присвячений фреймоворкам.
Книжка має всього 176 сторінок та опис понад 100 різних шаблонів. В цілому, книга дуже цікава! Підхід автора до постановки проблеми та висвітлення рішення мені особисто сподобався. Не буду казати, що ця книга must read, але якщо прочитаєте, то і самі все зрозумієте ;).
Spring 2.5: використання аннотацій
Основним моментом, який був для мене цікавим - це використання анотацій у доповнення до XML конфігурації. Саме про це я вирішив трохи написати.
Головним питанням було -- навіщо анотації?
Іншими цікавими питаннями були:
- які анотації можна використовувати?
- як їх використовувати?
- чи можливо працювати і дальше без них?
- як можна включати і виключати використання анотацій?
Отож, про все по порядку.
Анотації не підтримуються по замовчуванню. Для того, щоб їх використовувати, потрібно вказати Spring, що ви хочете працювати і з ними тоже. Для цьому слід добавити у ваш spring.xml наступний рядок:
<context:annotation-config/>.
Namespace context підключається так
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation=" http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"
Після цього, в нас появляється можливість використовувати анотації.
А тепер детальніше про самі анотанції. Так ми вже можемо використовувати їх, але які вони є, навіщо вони використовуються?
Найбільш поширеною видається анотації
@Autowired. Дана анотація, вказує що в контейнер Spring повинен виконати автоматичне встановлення значення. Дану анотацію можна використовувати для автоматичного встановлення значення в конструкторі, для поля класу, для сеттера. Наприклад:В даному випадку автозаповнення за допомогою анотації
public class DocumentManager {
@Autowired
private DocumentFinder documentFinder;
private DocumentDao documentDao;
private Document documentPrototype;
@Autowired
public DocumentManager(DocumentDao documentDao) {
this.documentDao = documentDao;
}
@Autowired
public void setPrototype(Document document) {
documentPrototype = prototype;
}
}
@Autowired, Spring буде виконувати на основі типів полів чи аргументів. Але виникає проблема, коли, наприклад, у вас може бути більше одного біна із типом DocumentFinder або Document. Що робити тоді, як Spring має знати яке саме значення слід вставити в певне поле? І саме тут вступає у гру анотація @Qualifier.Анотація
@Qualifier дозволяє вказати, який саме container-managed bean використовувати як значення для заповнення. Дану анотацію можна використовувати як для полів класу, так і для параметрів конструктора або інших методів, так само і для сеттерів. Назва біна, який повинен бути вставленим як значення поля чи параметра вказується як value анотації @Qualifier. Доволі просто і зручно, самі подивіться на код:
public class DocumentManager {
@Autowired
@Qualifier("defaultDocumentFinder")
private DocumentFinder documentFinder;
private DocumentDao documentDao;
private Document documentPrototype;
@Autowired
public DocumentManager(@Qualifier("hibernateDocumentDao")DocumentDao documentDao) {
this.documentDao = documentDao;
}
@Autowired
public void setPrototype(@Qualifier("prototypeDocument")Document document) {
documentPrototype = prototype;
}
}
Доречі, Spring дозволяє за допомогою XML вказати явно, який
qualifier у певного bean. Для цього використовується піделемент <qualifier> елемента <bean>. Він має такі атрибути, як:- type - тип анотації, що використовується (про це пізніше)
- value - це значення унікальне для даного біна.
Наприклад, якщо в коді вказано:
@Autowired
@Qualifier("prototypeDocument")
public void setPrototype(Document document) {
documentPrototype = prototype;
}
, то в XML
<bean class="Document">
<qualifier value="prototypeDocument"/>
</bean>
<bean class="Document">
<qualifier value="privateDocument"/>
</bean>
І як ви вже певно зрозуміли, при автозаповнення буде використаний перший bean, тому що його
qualifier value є prototypeDocument.Але це ще не всі можливості, які надає Spring у питанні вирішення, який саме bean повинен бути використаний для автозаповнення. Так, наприклад, ви можете створювати власні анотації, які використовувати замість
@Qualifier.Наприклад:
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface DocumentFinder {
String documentType();
String finderScope();
}
тоді
а в XML
@Autowired
@DocumentFinder(documentType="MSWord", finderScope="local")
private DocumentFinder documentFinder;
<bean class="DocumentFinder">
<qualifier type="annotation.DocumentFinder">
<attribute name="documentType" value="MSWord"/>
<attribute name="finderScope" value="local"/>
</qualifier>
</bean>
І це ще навіть не всі можливості...
Так, наприклад, я не розказав про
@Resource. А також і не згадав досі про можливість використання компонентів, які оголошенні за допомогою анотацій.Але про це все або читайте в туторіалі від Spring або вже у наступній статті.
Кешування другого рівня в Hibernate.
Кеш другого рівня в Hibernate може бути підключеним і може бути в межах процесу або кластера. Можуть бути різні реалізації кешу другого рівня, існують кілька вже готових реалізацій на основі готових движків кешування. Але можна реалізувати власний движок і підключити його за допомогою реалізації інтерфейсу org.hibernate.cache.CacheProvider.
Визначають наступні провайдери кешу другого рівня
- EHCache. Підтримка кешування другого рівня в межах одного процесу однієї віртуальної машини. Може виконувати зберігання кешу як в оперативній памяті, так і на диск. Підтримує кешування запитів.
- OSCache (OpenSymphony Cache). Підтримка кешування другого рівня в межах одного процесу однієї віртуальної машини. Підтримує кешування запитів.
- SwarmCache. Підтримка кешування другого рівня в межах кластера. Не підтримує кешування запитів.
- JBossCache. Підтримка кешування другого рівня в межах кластера. Підтримує кешування запитів.
Про підтримку стратегій кешування різними провайдерами можна дізнатися із наступної таблиці:
| Провайдер | Read-only | Read-write | Nonstrict-read-write | Transactional |
| EHCache | + | + | + | |
| OSCache | + | + | + | |
| SwarmCache | + | | + | |
| JBossCache | + | | | + |
Підтримка кешування другого рівня в Hibernate
Кешування другого рівня в Hibernate потрібно увімкнути, для того, щоб його використовувати. Увімкнути кешування другого рівня можна встановши property в конфігурації сесії Hibernate:
<property name="cache.use_second_level_cache">true</property>
Якщо необхідно увімкнути також кешування для запитів, то слід також встановити значення для property в конфігурації сесії Hibernate:
<property name="hibernate.cache.use_query_cache">true</property>
Також необхідно вказати клас провайдера кешування, а для цього треба задати наступний property в конфігурації сесії Hibernate :
- для провайдера EHCache
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
- для провайдера OSCache
<property name="cache.provider_class">org.hibernate.cache.OSCacheProvider</property>
- для провайдера SwarmCache
<property name="cache.provider_class">org.hibernate.cache.SwarmCacheProvider</property>
Але для того, щоб кешування другого рівня було в дії, слід позначити хоча б один клас для кешування. Позначити певний клас для кешування можна двома способами:
- В описі маппінгу класу у файлі *.hbm.xml добавити елемент cache із відповідним значенням.
<class name=”org.prisoft.sample.hibernate.Country” table=”Country” mutable="false">
<cache usage="read-only"/>
…
</class>
Вище описаний клас Country, який мапиться на таблицю Country. Ця таблиця є словником країн. Словник зміні не підлягає, тобто значення не добавляється, не редагується та не видаляється. <cache> вказує на те, що дані підлягають кешуванню, стратегія кешування read-only.
- У файлі конфігурації сесії hibernate.cfg.xml. Для цього використовується елемент <class-cache>, який наводиться після списку ресурсів. Ось як може описуватися кешування для класу Country:
<hibernate-configuration>
<session-factory>
….
<mapping resource=”org/prisoft/sample/hibernate/Country.hbm.xml”/>
….
<class-cache class=”org.prisoft.sample.hibernate.Country”
usage=”read-only”/>
</session-factory>
</hibernate-configuration>
Я надаю перевагу конфігурації кешування другого рівня через файл hibernate.cfg.xml, оскільки так видно повний список класів, що підлягають кешуванню, а також при необхідності, можна легко відключити кешування.
Отже, ми розглянули, як включити кешування другого рівня, а також як вказати які саме ентіті підлягають кешуванню. Ми не розглянули, як задається кешування для запитів.
Також ми не розглянули таке поняття, як регіони. Регіони – це так би мовити іменовані екземпляри кешу, в якому знаходяться різні класи із різними політиками часу на існування. По замовчуванню, ім’я регіону складає повна назва класу (якщо це кеш класу) або повна назва класу плюс імя property класу (якщо це колекція). За допомогою property сесії Hibernate hibernate.cache.region_prefix. Тоді ім’я регіону буде складатися із префіксу та повного імені класу. Вказати ім’я регіону можна явно за допомогою атрибута region в елементі <cache> або <class-cache>.
EHCache (http://ehcache.sourceforge.net)
Останнє обновлення аплікації це є ehcache-1.4-beta, яка вийшла 1 січня 2008. А це означає, що продукт не тільки живий, але і розвивається. Розповсюджується EhCache за ліцензією The Apache Software License, Version 2.0. Спонсори там також далеко не з послідніх. Так що, проект живе і розвивається. Не може не радувати повна підтримка JSR107 (JCache API).
Серед вказаних характеристик слід відзначити:
- Простота (API є досить простим, початкова конфігурація також не є необхідною).
- Залежність тільки від commons-logging та commons-collections. Вони в свою чергу також поширюються за APL. Та й більшість проектів їх використовує. То ж, ця залежність не є проблематичною.
- Кешування в оперативній пам’яті та на диск. Підтримка великих розмірів.
- Підтримка великої кількості кешів.
- Підтримка розширень для кешу (а також розширення для загружчиків та обробників виключень).
- А також багато чого іншого, про що ви можете точніше дізнатися за адресом http://ehcache.sourceforge.net/features.html
Як уже зазначено, можна і не конфігурувати EHCache. Але я не думаю, що це хороша ідея. Нам вона явно не підходить. Ми повинні навчитися конфігурувати EhCache.
Отже, конфігурація EHCache знаходиться у файлі ehcache.xml, який у свою чергу знаходиться в класспасі аплікації.
Отже, структура конфігураційного файла:
<ehcache>
<diskStore …/>
<defaultCache …/>
<cache name=”...” …/>
</ehcache>
Конфігураційний файл може містити не тільки ці елементи, але й інші. Але вони розглядатися не будуть.
Роглянемо детальніше ці елементи.
<diskStore path=”java.io.tmpdir”/> - вказує шлях до каталогу, де файли кешу створюються.
Наступні значення є можливими:
- user.home – домашній каталог користувача;
- user.dir – текучий робочий каталог користувача;
- java.io.tmpdir – каталог тимчасових файлів.
Можна також вказувати субдиректорії, наприклад <diskStore path=”java.io.tmpdir/cache/myapp”/>
Конфігурація кешу, який не описаний за допомогою власного <cache> елемента, відбувається через <defaultCache>.
<defaultCache
maxElementsInMemory=”
eternal=”false”
timeToIdleSeconds=”
timeToLiveSeconds=”
overflowToDisk=”true”
diskSpoolBufferSizeMB=”
maxElementsOnDisk=”
diskPersistent=”false”
diskExpiryThreadInternalSeconds=”
memoryStoreEvictionPolicy=”LRU”/>
Можна також задавати конфігурацію для окремого кешу; а для цього використовується наступний елемент
<сache name=”CacheName”
maxElementsInMemory=”
eternal=”false”
timeToIdleSeconds=”
timeToLiveSeconds=”
overflowToDisk=”true”
maxElementsOnDisk=”
diskPersistent=”false”
diskExpiryThreadInternalSeconds=”
memoryStoreEvictionPolicy=”LRU”/>
А тепер детальніше про кожен атрибут.
mame – назва кешу; назва, як ви вже, мабуть, зрозуміли має бути унікальна.
maxElementsInMemory – максимальна кількість об’єктів, які будуть створені та зберігатися в кеші в оперативній пам’яті.
maxElementsOnDisk – максимальна кількість об’єктів, які будуть збережені на диск.
eternal – вказує на те, чи є елементи вічними. Якщо вони є вічними, то будь-які настройки Idle та Live Seconds ігноруються, елементи зберігаються до кінця.
timeToIdleSeconds – час життя невикористаного елемента кешу (за умови, якщо eternal рівний false). Якщо значення 0, то це значить, що елемент може залишатися в кеші в стані не використовуваного нескінченний період.
timeToLiveSeconds – час життя елемента кешу (за умови, якщо eternal рівний false). Якщо значення 0, то це значить, що елемент може залишатися в кеші в стані невикористаного нескінченний період.
overflowToDisk – вказує на те, чи зберігати елементи на диск, якщо досягнуто максимуму елементів в пам’яті.
diskPersistent - чи зберігаються закешовані дані між пере запуском віртуальної машини. Значення по-замовчуванню false.
diskExpiryThreadInternalSeconds – кількість секунд, через які відбувається запуск потоку очищення диску від елементів кешу, що завершили свій час життя.
memoryStoreEvectionPolicy. Розрізняються наступні політики LRU – Least Recently Used, FIFO – First In First Out, LFU – Last Frequently Used.
Приклад аплікації із використанням кешу EHCache
Отже, розглянуто трохи теорії, а тепер ближче до практики. Для цього було створено просту аплікацію, яка містить 4 доменних об’єкта: Country, Materials, Product, ProductMaterial.
Отже, ми маємо аплікацію, яка містить інформацію про матеріали (назва, код, ціна, країна виробник), про продукцію (назва, код, ціна, країна виробник, матеріали із яких виготовлена продукція) і власне словник країн виробників.
Кешування класів та стратегії кешування описані у файлі hibernate.cfg.xml.
Отже, hibernate.cfg.xml має вигляд:
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.url">jdbc:mysql://localhost/proregister</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password"/>
<property name="hibernate.show_sql">false</property>
<mapping resource="org/prisoft/sample/proregister/objects/Country.hbm.xml"/>
<mapping resource="org/prisoft/sample/proregister/objects/Material.hbm.xml"/>
<mapping resource="org/prisoft/sample/proregister/objects/Product.hbm.xml"/>
<mapping resource="org/prisoft/sample/proregister/objects/ProductMaterial.hbm.xml"/>
<class-cache class="org.prisoft.sample.proregister.objects.Country" usage="read-only"/>
<class-cache class="org.prisoft.sample.proregister.objects.Material" usage="read-write"/>
<class-cache class="org.prisoft.sample.proregister.objects.Product" usage="read-write"/>
<class-cache class="org.prisoft.sample.proregister.objects.ProductMaterial" usage="read-write"/>
</session-factory>
</hibernate-configuration>
Клас Country має стратегію кешування read-only, в той час як всім іншим задана стратегія read-write. Country є по факту незмінним словником країн; його не можна змінювати.
Кеши класів Material, Product та ProductMaterial повинні підтримувати зміну, оскільки елементи можуть як добавлятися, так і редагуватися та видалятися. Саме тому їм задана стратегія read-write.
Аплікація працюватиме із базою даних на одній машині, тому виконувати кешування на диск немає потреби. Окрім того, кількість даних є невеликою, тому їх можна спокійно зберігати в базу даних.
Для детальної конфігурації EHCache потрібно конфігурувати кожен кеш у файлі ehcache.xml.
Отже, конфігурація має наступний вигляд:
<ehcache>
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"/>
[тут має бути конфігурація кешів, розглянута дальше]
</ehcache>
Отже, ми вказали на каталог для файлів кешування та конфігурацію кешу по-замовчуванню.
Нижче подана конфігурація кешу для класу Country. Задаємо максимальну кількість елементів в пам’яті, забороняється записувати дані на диск, дані можуть зберігатися тривалий час. Якщо кількість елементів в пам’яті перевищує 200, то тоді відбувається очистка кешу.
<cache name="org.prisoft.sample.proregister.objects.Country "
maxElementsInMemory="200"
eternal="true"
overflowToDisk="false"/>
Настройка кешу для об’єктів Product, Material та ProductMaterial має відмінності, оскільки ці об’єкти можуть змінюватися, тому для них задана конфігурація тривалості існування елементів кешу. Конфігурація подана нижче.
<cache name=”org.prisoft.sample.proregister.Product”
maxElemenentsInMemory=”
eternal=”false”
overflowToDisk=”false”
timeToIdleSeconds=”
timeToLiveSeconds=”300”/>
<cache name=”org.prisoft.sample.proregister.Material”
maxElemenentsInMemory=”
eternal=”false”
overflowToDisk=”false”
timeToIdleSeconds=”
timeToLiveSeconds=”300”/>
<cache name=”org.prisoft.sample.proregister.ProductMaterial”
maxElemenentsInMemory=”
eternal=”false”
overflowToDisk=”false”
timeToIdleSeconds=”
timeToLiveSeconds=”120”/>
Як бачите, для різних кешів задана різна кількість елементів в памяті. Атрибут eternal має значення false, тому конфігурація періоду існування елементів у кеші не буде ігноруватися. Дані не зберігаються на диск для жодного із кешів, використовуваних в аплікації.
Отже, ми розглянули які існують провайдери кешу другого рівня для Hibernate, також ми розглянули, як настроїти Hibernate для використання кешу другого рівня для класів (проте не зачепили теми кешування запитів та колекцій). Розглянуто було також більш детально провайдер EHCache.
Додаткова література
1. Hibernate In Action, Manning Publications, 2005
2. EhCache User Guide at http://ehcache.sourceforge.net/EhcacheUserGuide.html
Кешування другого рівня в Hibernate.
Частина I: Трохи теорії
Є багато способів пришвидшити роботу Hibernate. Одним із них є кешування другого рівня (second level cache).
Для мене він знадобився при оптимізації роботи проекту, який використовує Hibernate 3.2.3. В межах аплікації використовується кілька наборів даних, які рідко змінюються. Декотрі дані взагалі не змінюються. Витягувати їх із бази даних кожен раз виходить доволі накладно і навіть довго. Після використання кешування, на звичайній машині різниця почала відмічатися одразу ж.
Взагалі про розгляді кешування в Hibernate, слід розрізняти кешування першого та другого рівнів. Кешування першого рівня є обовязковим, його не можна відключити. Це є кешування рівня одиниці виконання роботи (unit of work) і виконується воно через Session.
Трохи детальніше про кешування першого рівня, адже воно є необхідним для розуміння кешування другого рівня. Перш за все, слід зрозуміти, що це є кешування перстистетних об'єктів, тобто, в межах однієї Session, кешуються об’єкти класу, а не окремі дані, і отримуються для одного і того самого же рядка в базі даних один і той самий об'єкт. Що ж це дає, і чому зрозблено саме так? По-перше, це дозволяє виконувати ідентифікацію по об’єкту, а не по значенню в межах однієї сесії. По-друге, це дозволяє зберігати інформацію про зміни до рядку в межах одного об’єкта, що уже спасає від будь-яких подальших проблем пов’язаних із синхронізацією із базою даних. Отже, кешування першого рівня, використовується в межах сесії одного користувача, і не впливає на роботу інших користувачів. Це пришвидшує роботу.
Кешування другого рівня має зовсім інші межі використання. Навідміну від кешування першого рівня (яке використовується в межах запиту користувача або бізнес транзакції користувача), кешування другого рівня використовується в межах процесу або кластера виконання аплікації. Цей кеш є спільним для багатьох користувачів системи, відповідно, його потрібно осторожно використовувати, та володіти основними правилами.
Перш за все, слід сказати, що кеш другого рівня в Hibernate може мати межі процесу або кластера. Всі сесії використовують спільний кеш. Фактично кеш другого рівня має межі SessionFactory, в той час як кеш першого рівня має межі Session.
Для того, щоб робота кешу другого рівня була задовільною в багатокористувацькому середовищі, слід розуміти стратегії кешування. Стратегія кешування для об’єкта кешування встановлюється незалежно.
Так виділяють наступні стратегії кешування:
- read-only – для об’єктів, що не змінюються ніколи в межах роботи аплікації.
Типове для використання у випадку, якщо значення об’єктів не змінюється в процесі роботи аплікації (наприклад, ролі користувачів, список країн, мов, інші специфічні словники). Для подібних об’єктів можна також використовувати mutable = “false”, що дозволяє Hibernate пришвидшувати роботу для незмінюваних об’єктів.
- read-write – для об’єктів, що можуть змінюватися в межах роботи аплікації, але частота зміни не є великою.
Підходить для використання у більшості випадків. Велика кількість об’єктів в системі змінюється, але при цьому кешування об’єктів є необхідною для покращення роботи.
- nonstrict read-write – для об’єктів, що можуть змінюються в процесі роботи аплікації дуже рідко.
Кеш другого рівня дозволяє зберігати дані як в оперативній пам’яті так і на жорсткому диску. Зберігання даних на жорсткому диску актуально у випадках, коли аплікація та база даних знаходяться на різних машинах.
Коли відбувається загрузка об’єкта за допомогою Session, перш за все, Session виконує перевірку кешу на рахунок наявності в ньому об’єкту із відповідною значенням поля ідентифікації. Перевірка виконується у випадку, якщо для даного типу включено кешування другого рівня. Отже, якщо кеш містить закешований об’єкт відповідним значенням поля ідентифікації, то відбувається створення ново об’єкта у віртувальній машині та заповнення його даними.
Звідси можна зробити наступний висновок. В кеші зберігаються не об’єкти віртуальної машини, а прості дані. На основі цих даних, відбувається заповнення новоствореного об’єкту.
Якщо ж кеш не містить шуканий об’єкт, то відбувається запит до бази даних, і якщо рядок із таким ідентифікатором все-таки є в базі даних, то відбувається його поміщення в кеш. Тепер кеш містить запис для рядка із даним ідентифікатором.