Доброго времени суток всем! Есть проблема (либо непонимание) hibernate.
Обрисую ситуацию:
Приложение Grails с накрученным UI на Vaadin.
Если развернуть, то это java и объекты клиентской сессии, создаваемые при подключении нового пользователя
Работа с данными через hibernate + ehcache
Включен кэш второго уровня. Имеем пару G(ORM) объектов:
class MyObject{
def MyObjectType objectType
...
static mapping = {
objectType(lazy: false)
cache true
}
}
class MyObjectType {
...
static mapping = {
cache true
}
}
На сколько я понимаю кэш второго уровня — не должны создаваться новые экземпляры G(ORM) класса до тех пор, пока объект в кэше и не изменялся.
У MyObjectType определены hashCode и equals.
Идем дальше. Работа в рамках одной сессии:
Получение списка объектов MyObject.
При каждом получении списка MyObject в памяти создаются новые экземпляры MyObjectType (проверено профайлером), хотя по логике должен браться существующий экземпляр из кэша.
Есть какое-нибудь объяснение?
Вроде как решается выставлением lazy=true, и вызовом MyObject.findById(..) в случае обращения
(хотя вроде это должен сделать ehcache при получении MyObject).
В этом случае объект читается из кэша и все хорошо,
но только в рамках одной сессии.
Как только второй пользователь открывается и выполняет тот же код — создаются новые экземпляры MyObjectType. То есть основная проблема в том, что Hibernate Cache работает в рамках одной пользовательской сессии, а хотелось бы, чтобы он работал в рамках виртуальной машины.
Настройки кэша:
DataSource.groovy
hibernate {
cache.use_second_level_cache = true
cache.use_query_cache = true
cache.provider_class = 'org.hibernate.cache.EhCacheProvider'
}
ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd">
<defaultCache maxElementsInMemory="100"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600"
overflowToDisk="false"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"/>
<cache name="com.test.MyObjectType"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600"
overflowToDisk="false"/>
</ehchache>
----
В целом у меня здесь должно быть 2 кэшируемых объекта.
Но вообще связка {некешируемый объект = {кэшируемый объект,...}} почему-то не очень работает. Кэшируемые объекты не должны плодиться, а они только этим и занимаются
хтбернэйт кэширует не объекты, а кортежи значений, из которых потом когда требуется строит объекты.