java - hibernate 二级 ehcache 未命中

标签 java hibernate ehcache

我正在尝试使用 ehcache 实现使二级 hibernate 缓存工作。

我确定这是我犯的一些明显的菜鸟错误,但我看不出它是什么!

为了测试我的缓存,我正在执行以下操作:

创建一个对象并保存它。我在事务中“获取”了一次,在那里我可以看到我在没有数据库命中的情况下取回了对象,这只是 hibernate 一级缓存在做它的事情。

然后我提交事务并开始一个新 session 。

这一次,当我“获取”对象时,我可以在调试中看到来自 ehcache 的缓存未命中。自从我在之前的事务中保存了该对象后,我就希望该对象现在在缓存中?

这是我的代码:

  Session session = getSession();   
  session.beginTransaction();

  Test1 test1a = new Test1();
  test1a.setId(5);
  test1a.setName("Test 1");
  test1a.setValue(10);
  // Touch it
  session.save(test1a);

  // Now get it
  Test1 test1b = (Test1)session.get(Test1.class, 5);

  // Within a transaction, the session caches it - no db hit
  System.out.println("GOT object with value "+test1b.getValue());

  session.getTransaction().commit();

  System.out.println("Between sessions");

  session = getSession();
  session.beginTransaction();

  test1b = (Test1)session.get(Test1.class, 5);

  System.out.println("GOT object with value "+test1b.getValue());

  session.getTransaction().commit(); 

这是我的 hibernate.cfg.xml 的相关部分

<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

还有我的ehcache.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://ehcache.sf.net/ehcache.xsd"> 
    <cache name="com.play.hibernate1.Test1" maxElementsInMemory="1000" eternal="false"     timeToLiveSeconds="600" overflowToDisk="false"/>
    <defaultCache maxElementsInMemory="10000" eternal="false"
overflowToDisk="true" timeToIdleSeconds="10" timeToLiveSeconds="20" diskPersistent="true" />
    </ehcache>

还有我的注释

@Entity
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Test1 {

调试日志

11:21:03,474 DEBUG CacheManager:239 - Configuring ehcache from classpath.
11:21:03,479 DEBUG ConfigurationFactory:122 - Configuring ehcache from ehcache.xml found in the classpath: file:/Users/bw/Documents/workspace/hibernate1/target/classes/ehcache.xml
11:21:03,479 DEBUG ConfigurationFactory:87 - Configuring ehcache from URL: file:/Users/brucewood/Documents/workspace/hibernate1/target/classes/ehcache.xml
11:21:03,480 DEBUG ConfigurationFactory:139 - Configuring ehcache from InputStream
11:21:03,485 DEBUG BeanHandler:213 - Ignoring ehcache attribute xmlns:xsi
11:21:03,485 DEBUG BeanHandler:213 - Ignoring ehcache attribute xsi:noNamespaceSchemaLocation
11:21:03,517 DEBUG ConfigurationHelper:208 - No CacheManagerEventListenerFactory class specified. Skipping...
11:21:03,518 DEBUG ConfigurationHelper:183 - No CachePeerListenerFactoryConfiguration specified. Not configuring a CacheManagerPeerListener.
11:21:03,518 DEBUG ConfigurationHelper:159 - No CachePeerProviderFactoryConfiguration specified. Not configuring a CacheManagerPeerProvider.
11:21:03,525 DEBUG ConfigurationHelper:135 - No BootstrapCacheLoaderFactory class specified. Skipping...
11:21:03,526 DEBUG ConfigurationHelper:135 - No BootstrapCacheLoaderFactory class specified. Skipping...
11:21:03,532 DEBUG MemoryStore:73 - Initialized net.sf.ehcache.store.LruMemoryStore for com.play.hibernate1.Test1
11:21:03,533 DEBUG LruMemoryStore:71 - com.play.hibernate1.Test1 Cache: Using SpoolingLinkedHashMap implementation
11:21:03,533 DEBUG Cache:429 - Initialised cache: com.play.hibernate1.Test1
1528 [Finalizer] INFO org.hibernate.connection.DriverManagerConnectionProvider - cleaning up connection pool: jdbc:mysql://localhost:3306/play
1668 [main] INFO org.hibernate.impl.SessionFactoryObjectFactory - Not binding factory to JNDI, no JNDI name configured
GOT object with value 10
Hibernate: 
    /* insert com.play.hibernate1.Test1
        */ insert 
        into
            Test1
            (name, value, id) 
        values
            (?, ?, ?)
1274984463818|1|1|batch|/* insert com.play.hibernate1.Test1 */ insert into Test1 (name, value, id) values (?, ?, ?)|/* insert com.play.hibernate1.Test1 */ insert into Test1 (name, value, id) values ('Test 1', 10, 5)
1274984463820|1|1|statement|/* insert com.play.hibernate1.Test1 */ insert into Test1 (name, value, id) values (?, ?, ?)|/* insert com.play.hibernate1.Test1 */ insert into Test1 (name, value, id) values ('Test 1', 10, 5)
1274984463821|1|1|commit||
Between sessions
11:21:03,823 DEBUG EhCache:68 - key: com.play.hibernate1.Test1#5
11:21:03,823 DEBUG MemoryStore:138 - com.play.hibernate1.Test1Cache: com.play.hibernate1.Test1MemoryStore miss for com.play.hibernate1.Test1#5
11:21:03,823 DEBUG Cache:661 - com.play.hibernate1.Test1 cache - Miss
11:21:03,824 DEBUG EhCache:77 - Element for com.play.hibernate1.Test1#5 is null
Hibernate: 
    /* load com.play.hibernate1.Test1 */ select
        test1x0_.id as id0_0_,
        test1x0_.name as name0_0_,
        test1x0_.value as value0_0_ 
    from
        Test1 test1x0_ 
    where
        test1x0_.id=?
1274984463829|4|1|statement|/* load com.play.hibernate1.Test1 */ select test1x0_.id as id0_0_, test1x0_.name as name0_0_, test1x0_.value as value0_0_ from Test1 test1x0_ where test1x0_.id=?|/* load com.play.hibernate1.Test1 */ select test1x0_.id as id0_0_, test1x0_.name as name0_0_, test1x0_.value as value0_0_ from Test1 test1x0_ where test1x0_.id=5
1274984463831|-1||resultset|/* load com.play.hibernate1.Test1 */ select test1x0_.id as id0_0_, test1x0_.name as name0_0_, test1x0_.value as value0_0_ from Test1 test1x0_ where test1x0_.id=5|name0_0_ = Test 1, value0_0_ = 10
GOT object with value 10
1274984463834|0|1|commit||

感谢您的帮助!

最佳答案

问题是我使用的是 NONSTRICT_READ_WRITE。它似乎符合文档中此解释的要求:

If the application only occasionally needs to update data (i.e. if it is extremely unlikely that two transactions would try to update the same item simultaneously), and strict transaction isolation is not required, a nonstrict-read-write cache might be appropriate. If the cache is used in a JTA environment, you must specify hibernate.transaction.manager_lookup_class. In other environments, you should ensure that the transaction is completed when Session.close() or Session.disconnect() is called.

但实际上它看起来并没有将保存的对象添加到缓存中.. IMO,这里的文档有点薄。在 Java Persistence with Hibernate 中对缓存选项有更好的处理,尽管在对数据实际发生的事情的具体解释上仍然有点薄弱。无论如何..

我将缓存选项更改为 READ_WRITE,现在它按预期工作。

另请注意,第一次将对象添加到缓存中时,您会在 ehcache 调试中看到“缓存未命中”。据推测,它在其缓存中查找,发现该对象不存在,记录未命中,然后添加该对象。之后,您会获得“命中”。

关于java - hibernate 二级 ehcache 未命中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2923775/

相关文章:

Java - 音标 - 将一种格式转换为 SAMPA 格式

java - Spring Boot事务回滚

java - Ehcache 低内存行为

java - Spring @Cacheable : Preserve old value on error

java - Hibernate 分离标准

java - Spring上下文属性-占位符ehcache配置

java - 这里是否有不使用 getter 和 setter 的情况?

java - 扫描仪没有拾取文件的内容?

java - 使用模拟对方法进行单元测试

java - Spring hibernate jdbc 批量大小