EclipseLink のキャッシュの中身を表示するサンプル
EclipseLink で L2 レベルのキャッシュ(Persistence Unit Cache という言うみたいです。persistence unit 単位のキャッシュですね)の中身を表示するサンプルです。EclipseLink では JpaCache というインタフェースが用意されていて、こいつがキャッシュの内容を表示する API を提供してくれている感じです。JpaCache の取得方法は EntityManagerFactory#getCache() で取れます。
・EclipseLink/Examples/JPA/Caching - Eclipsepedia
https://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching
・JpaCache (EclipseLink 2.1.2, build 'v20101206-r8635' API Reference)
http://www.eclipse.org/eclipselink/api/2.1/org/eclipse/persistence/jpa/JpaCache.html
以下がサンプル。いろいろ余計な処理がありますが、キャッシュを表示しているのは printCache() になります。
■ Main.java
package com.sample; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import org.eclipse.persistence.jpa.JpaCache; import com.sample.entity.Test; public class Main { private static final String PERSISTENCE_UNIT_NAME = "test"; private static EntityManager em; public static void main(String[] args) { findTest(1); findTest(2); printCache(); findTest(3); printCache(); } public static void persistTest(int id, String name) { Test t = new Test(); t.setId(id); t.setName(name); EntityManager em = getEntityManager(); em.getTransaction().begin(); em.persist(t); em.getTransaction().commit(); em.close(); } public static void findTest(int id) { EntityManager em = getEntityManager(); Test t = em.find(Test.class, id); System.out.println("findTest() : " + t); } public static void printCache() { JpaCache cache = (JpaCache)em.getEntityManagerFactory().getCache(); //System.out.println(cache); cache.print(); } public static EntityManager getEntityManager() { if (em == null) { EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); em = factory.createEntityManager(); } return em; } }
実行すると以下の感じ。★をつけた箇所が JpaCache#print() の出力です。find で Test のエンティティを取得するとキャッシュにのっていることが確認できますね。次に同じエンティティを取得する際は実際に DB には接続せずにキャッシュから取得されるはずです(ここはちゃんと確認はしてません)。
■ 実行結果
[EL Info]: 2016-12-29 16:59:07.952--ServerSession(1589931229)--EclipseLink, version: Eclipse Persistence Services - 2.5.0.v20130507-3faac2b [EL Info]: connection: 2016-12-29 16:59:08.082--ServerSession(1589931229)--file:/C:/devspace/workspace45/EclipseLinkSample/target/classes/_test login successful findTest() : 1:name1 findTest() : 2:name2 [EL Severe]: cache: 2016-12-29 16:59:08.156--ServerSession(1589931229)-- ★ SoftCacheWeakIdentityMap for: Test ★ Key: 1 Identity Hash Code: 382044126 Object: 1:name1 ★ Key: 2 Identity Hash Code: 1289454852 Object: 2:name2 ★ 2 elements ★ findTest() : 3:name3 [EL Severe]: cache: 2016-12-29 16:59:08.16--ServerSession(1589931229)-- ★ SoftCacheWeakIdentityMap for: Test ★ Key: 1 Identity Hash Code: 382044126 Object: 1:name1 ★ Key: 2 Identity Hash Code: 1289454852 Object: 2:name2 ★ Key: 3 Identity Hash Code: 551421413 Object: 3:name3 ★ 3 elements ★
取れてくる値がおかしいなり、なんとなくキャッシュまわりではまった際は、一度、上記の方法でキャッシュの中身を見てみるといいかもしれません。
以下、一応、Entity Class、persistence.xml をのせておきます。
■ Test.java(Entity Class)
package com.sample.entity; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; @Entity public class Test { public Test() {} @Id @Column(name="id") private int id; @Column(name="name") private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String toString() { return id + ":" + name; } }
■ persistence.xml
<?xml version="1.0" encoding="UTF-8" ?> <persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"> <persistence-unit name="test" transaction-type="RESOURCE_LOCAL"> <class>com.sample.entity.Test</class> <properties> <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" /> <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/postgres" /> <property name="javax.persistence.jdbc.user" value="postgres" /> <property name="javax.persistence.jdbc.password" value="postgres" /> <!-- EclipseLink should create the database schema automatically --> <property name="eclipselink.ddl-generation" value="create-tables" /> <property name="eclipselink.ddl-generation.output-mode" value="database" /> </properties> </persistence-unit> </persistence>
簡単ですが、以上になります。
[検証環境]
Windows 10
Java SE 8 Update 92
EclipseLink 2.5.0
PostgreSQL JDBC Driver 9.4.1212
PostgreSQL 9.5