I have big issue with Ehcache configuration.
I use:
ehcache 2.6.2
hibernate 3.3.1 GA
My current configuration is next:
1) Hibernate
<bean id="hibernateProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.default_schema">#db.schema#</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="connection.pool_size">10</prop>
<prop key="hibernate.jdbc.batch_size">30</prop>
<prop key="hibernate.default_batch_fetch_size">30</prop>
<prop key="hibernate.max_fetch_depth">30</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">
net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory
</prop>
<prop key="net.sf.ehcache.configurationResourceName">
/ehcache-config.xml
</prop>
<prop key="hibernate.generate_statistics">true</prop>
</props>
</property>
</bean>
2) ehcache-config.xml
<ehcache name="xxxx">
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
<cache name="org.hibernate.cache.UpdateTimestampsCache"
maxEntriesLocalHeap="5000"
eternal="true">
<persistence strategy="localTempSwap"/>
</cache>
<cache name="org.hibernate.cache.StandardQueryCache"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
diskExpiryThreadIntervalSeconds="120">
<persistence strategy="localTempSwap"/>
</cache>
</ehcache>
All java-objects implements Serializable and I use read-write caching, all queries is setCacheable(true), but I still can't see performance improvements.
First of all, I have many messages like this:
19:30:51,829 DEBUG [Segment] fault added 0 on disk
19:30:51,829 DEBUG [Segment] put added 0 on heap
19:30:51,829 DEBUG [Segment] fault removed 0 from heap
19:30:51,829 DEBUG [Segment] fault added 0 on disk
19:30:51,829 DEBUG [Segment] put added 0 on heap
19:30:51,830 DEBUG [Segment] fault removed 0 from heap
19:30:51,830 DEBUG [Segment] fault added 0 on disk
And the most important thing that I have noticed: all attempts to use cache ends with:
1) 19:30:47,396 DEBUG [EhcacheGeneralDataRegion] Element for key sql: **** is null
2) 20:26:31,939 DEBUG [EhcacheGeneralDataRegion] key: ****
20:26:31,939 DEBUG [EhcacheGeneralDataRegion] Element for key **** is null
Thank you for your assistance.
Best regards.
Related
We use a level 2 cache in the project (hibernate ehcache version 5.6.3):
<props>
<property name="hibernateProperties">
<props> <prop key="shared-cache-mode">ENABLE_SELECTIVE</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop>
<prop key="net.sf.ehcache.configurationResourceName">ehcache.xml</prop>
<prop key="hibernate.cache.use_structured_entries">false</prop>
<prop key="hibernate.generate_statistics">true</prop>
</props>
In almost all requests, we get data from the cache in about 1 ms.
But one request to get a list of objects: when accessing the database -500 ms, from the cache - 100-500 ms,
Almost the same request, but on getting the number of objects: when accessing the database - 100 ms, from the cache - 1 ms,
The database is on localhost.
request cache:
<cache
name="query.FindDiscussionByFilter"
maxEntriesLocalHeap="500000"
eternal="false" timeToIdleSeconds="3600"
timeToLiveSeconds="3600"
memoryStoreEvictionPolicy="LRU"
statistics="true">
<persistence strategy="localTempSwap" />
</cache>
Is it possible to speed up the cache?
Is it possible to save data only in RAM?
Since they are immediately saved to disk.
I have two applications to use the same database with same schema. Application A will read write the table A. Application B will read the table A only.
If I configured 2nd Level cache in both applications. Application B will not retrieve the updated value which application A updated the record in table A before.
I want to configure the same hibernate config to share the same cache with multiple applications (in this case, application B can get the updated value)
I read some stackoverflow but still not work for me.
I am using hibernate 5 and using Ehcache for cache management.
Any idea how I might implement this? May I have any reference?
Here are some hibernate Properties in my both applications
Sprint hibernate config:
<bean id="mySessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="annotatedClasses">
<list>
...
</list>
</property>
<property name="hibernateProperties">
<props>
<!-- Debug -->
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto">none</prop>
<!-- Level two caching -->
<prop key="hibernate.cache.provider_class">=net.sf.ehcache.hibernate.EhCacheProvider</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
<prop key="net.sf.ehcache.configurationResourceName">../conf/ehcache.xml</prop>
</property>
</bean>
ehcache.xml:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd"
updateCheck="true" monitoring="autodetect"
dynamicConfig="true" >
<diskStore path="java.io.tmpdir"/>
<!-- Default cache settings -->
<defaultCache
maxElementsInMemory="100000"
eternal="true"
timeToIdleSeconds="300"
timeToLiveSeconds="300"
overflowToDisk="false"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="300"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
You can consider using distributed cache like Hazelcast. In fact Hazelcast has built-in integration with Hibernate to easily plug in for second-level caching
I have a problem with c3p0. Last time I configured c3p0 as dataSource in application because Quartz Scheduler opened new connection for every check, now is ok but from this time application doesnt respond after about 30mins, sometimes more. There is no logs in catalina or application logs file. Other applications work normally on the same server. On this application I got 404. I returned to default Spring data source and removed configuration and everything works.
What can cause the problem ?
Tomcat 8.0.21
c3p0.version 0.9.5.1
Hibernate version 4.3.1.Final
Configuration
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${db.driver}" />
<property name="jdbcUrl" value="${db.url}" />
<property name="user" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>
<property name="hibernateProperties">
<props>
<!-- HIBERNATE CONFIGURATION -->
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<!-- <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> -->
<prop key="hibernate.connection.characterEncoding">UTF-8</prop>
<prop key="hibernate.connection.useUnicode">true</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory
</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</prop>
<!-- HIBERNATE SEARCH CONFIGURATION -->
<prop key="hibernate.search.default.directory_provider">filesystem</prop>
<prop key="hibernate.search.default.indexBase">${hibernate.search.local}</prop>
<!-- CONNECTIONS POOLING CONFIGURATION -->
<prop key="hibernate.c3p0.acquire_increment">1</prop>
<prop key="hibernate.c3p0.idle_test_period">1</prop>
<prop key="hibernate.c3p0.max_size">60</prop>
<prop key="hibernate.c3p0.max_statements">0</prop>
<prop key="hibernate.c3p0.min_size">30</prop>
<prop key="hibernate.c3p0.timeout">0</prop>
</props>
</property>
</bean>
Update with new settings:
<prop key="hibernate.c3p0.acquire_increment">1</prop>
<prop key="hibernate.c3p0.idle_test_period">1000</prop>
<prop key="hibernate.c3p0.max_size">60</prop>
<prop key="hibernate.c3p0.max_statements">0</prop>
<prop key="hibernate.c3p0.min_size">20</prop>
<prop key="hibernate.c3p0.timeout">100</prop>
Still same, one user, 1h:40min
I am trying to verify if my ehcache configuration is working properly. So I put this code before and after the select. And my app execute the select all times for the same row... I did all my configuration using this tutorial. https://balamaci.wordpress.com/2009/12/07/caching-with-ehcache-part-i/
String msg = "select blockIscsi: " + storage.getStorageIndex();
System.out.println(msg);
blockIscsi = blockIscsiDAO.getByKey(storage.getStorageIndex(), Long.valueOf(storage.getPartitionId()));
System.out.println("done!");
select blockIscsi: 757
Hibernate: select this_.STORAGEINDEX as STORAGEI1_32_0_, this_.PARTITIONID as PARTITIO2_32_0_, this_.BLOCK_STATUS as BLOCK3_32_0_, this_.BLOCK_TYPE as BLOCK4_32_0_, this_.USTORE_ID as USTORE5_32_0_ from blocks this_ where this_.STORAGEINDEX=? and this_.PARTITIONID=?
done!
select blockIscsi: 757
Hibernate: select this_.STORAGEINDEX as STORAGEI1_32_0_, this_.PARTITIONID as PARTITIO2_32_0_, this_.BLOCK_STATUS as BLOCK3_32_0_, this_.BLOCK_TYPE as BLOCK4_32_0_, this_.USTORE_ID as USTORE5_32_0_ from blocks this_ where this_.STORAGEINDEX=? and this_.PARTITIONID=?
done!
select blockIscsi: 757
Hibernate: select this_.STORAGEINDEX as STORAGEI1_32_0_, this_.PARTITIONID as PARTITIO2_32_0_, this_.BLOCK_STATUS as BLOCK3_32_0_, this_.BLOCK_TYPE as BLOCK4_32_0_, this_.USTORE_ID as USTORE5_32_0_ from blocks this_ where this_.STORAGEINDEX=? and this_.PARTITIONID=?
done!
EDIT:
appContext.xml:
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.bytecode.use_reflection_optimizer">true</prop>
<!-- <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop> -->
<!-- <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory
</prop> -->
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
</prop>
<!-- enable second level cache and query cache -->
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="net.sf.ehcache.configurationResourceName">ehcache.xml</prop>
<prop key="hibernate.jdbc.batch_size">20</prop>
<prop key="hibernate.jdbc.fetch_size">25</prop>
<prop key="hibernate.order_inserts">true</prop>
<prop key="hibernate.order_updates">true</prop>
<prop key="hibernate.jdbc.batch_versioned_data">true</prop>
<prop key="hibernate.hbm2ddl.auto">none</prop>
<prop key="hibernate.c3p0.min_size">2</prop>
<prop key="hibernate.c3p0.max_size">100</prop>
<prop key="hibernate.c3p0.timeout">100</prop>
<prop key="hibernate.c3p0.max_statements">0</prop>
<prop key="hibernate.c3p0.maxIdle">-1</prop>
<prop key="hibernate.c3p0.idle_test_period">100</prop>
<prop key="hibernate.c3p0.acquire_increment">1</prop>
<prop key="hibernate.c3p0.unreturnedConnectionTimeout">30</prop>
<prop key="hibernate.c3p0.debugUnreturnedConnectionStackTraces">false</prop>
</props>
</property>
ehcache.xml:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
monitoring="autodetect" dynamicConfig="true">
<diskStore path="user.dir/ehcache" />
<defaultCache maxEntriesLocalHeap="10000" eternal="false"
timeToIdleSeconds="0" timeToLiveSeconds="1800" diskSpoolBufferSizeMB="80"
maxEntriesLocalDisk="10000000" diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU" statistics="true">
<persistence strategy="localTempSwap" />
</defaultCache>
<cache name="blockiscsi" maxEntriesLocalHeap="10000" eternal="false"
timeToIdleSeconds="5" timeToLiveSeconds="10">
<persistence strategy="localTempSwap" />
</cache>
<cache name="org.hibernate.cache.internal.StandardQueryCache"
maxEntriesLocalHeap="5" eternal="false" timeToLiveSeconds="120">
<persistence strategy="localTempSwap" />
</cache>
<cache name="org.hibernate.cache.spi.UpdateTimestampsCache"
maxEntriesLocalHeap="5000" eternal="true">
<persistence strategy="localTempSwap" />
</cache>
</ehcache>
DAO:
public BlockIscsi getByKey(Long id, Long partitionId) {
Session session = null;
BlockIscsi blockIscsi = null;
try {
session = currentSession();
Criteria criteria = session.createCriteria(BlockIscsi.class);
criteria.add(Restrictions.eq("id", id));
criteria.add(Restrictions.eq("partitionId", partitionId));
criteria.setCacheable(true);
criteria.setCacheRegion("query.blockiscsi");
blockIscsi = (BlockIscsi) criteria.uniqueResult();
} catch (GenericJDBCException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
} finally {
session.close();
}
return blockIscsi;
}
You have disabled query caching:
<prop key="hibernate.cache.use_query_cache">false</prop>
This means individual entities get cached (since your second level cache is on), but the result of your custom query (since you are doing a Criteria query, and not a Session.get()) is not cached. For that reason Hibernate has to go to the database and execute the query.
You need to enable both the query cache (to remember the identifiers of the entities returned by the query) and the second level cache (to remember the entities themselves).
See the Hibernate docs for more information: https://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch06.html
We have JBOSS 4.0.3.SP1 over TOMCAT 5.25.26 application server.
Usually it works fine, but about once a month we have "No ManagedConnections available"
Caused by: org.jboss.util.NestedSQLException: No ManagedConnections available within configured blocking timeout ( 5000 [ms] ); - nested throwable: (javax.resource.ResourceException: No ManagedConnections available within configured blocking timeout ( 5000 [ms] ))
at org.jboss.resource.adapter.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:79)
at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:82)
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:423)
... 73 more
Caused by: javax.resource.ResourceException: No ManagedConnections available within configured blocking timeout ( 5000 [ms] )
at org.jboss.resource.connectionmanager.InternalManagedConnectionPool.getConnection(InternalManagedConnectionPool.java:246)
at org.jboss.resource.connectionmanager.JBossManagedConnectionPool$BasePool.getConnection(JBossManagedConnectionPool.java:529)
at org.jboss.resource.connectionmanager.BaseConnectionManager2.getManagedConnection(BaseConnectionManager2.java:410)
at org.jboss.resource.connectionmanager.TxConnectionManager.getManagedConnection(TxConnectionManager.java:342)
at org.jboss.resource.connectionmanager.BaseConnectionManager2.allocateConnection(BaseConnectionManager2.java:462)
at org.jboss.resource.connectionmanager.BaseConnectionManager2$ConnectionManagerProxy.allocateConnection(BaseConnectionManager2.java:894)
at org.jboss.resource.adapter.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:73)
When I look in oracle sessions table I can see that there ara all 100 available connections are INACTIVE and the last sql was the one we use to check connection (select sysdate from dual).
Connection pool just cannot reuse them Why this can happen?
We have JNDI datasource defined in oracle-ds.xml like this:
<datasources>
<local-tx-datasource>
<jndi-name>ROT</jndi-name>
<connection-url>jdbc:oracle:thin:#ttt.tt.tt:1521:usr</connection-url>
<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
<user-name>usr</user-name>
<password>usrpass</password>
<min-pool-size>5</min-pool-size>
<max-pool-size>100</max-pool-size>
<idle-timeout-minutes>10</idle-timeout-minutes>
<track-statements>true</track-statements>
<blocking-timeout-millis>5000</blocking-timeout-millis>
<!-- Uses the pingDatabase method to check a connection is still valid before handing it out from the pool -->
<check-valid-connection-sql>select sysdate from dual</check-valid-connection-sql>
<metadata>
<type-mapping>Oracle9i</type-mapping>
</metadata>
</local-tx-datasource>
</datasources>
Here is the hibernate config for datasource:
<bean id="rotSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialec</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</prop>
<prop key="hibernate.jdbc.batch_size">20</prop>
<prop key="hibernate.connection.release_mode">after_statement</prop>
<prop key="hibernate.c3p0.min_size">5</prop>
<prop key="hibernate.c3p0.max_size">20</prop>
<prop key="hibernate.c3p0.timeout">300</prop>
<prop key="hibernate.c3p0.max_statements">50</prop>
<prop key="hibernate.c3p0.idle_test_period">3000</prop>
</props>
</property>
<property name="dataSource" ref="dataSource"/>
Data source in hibernate: