Book と Author の 2 つのエンティティがあります。本には著者のコレクションがあります。Book エンティティとその Authors を保持するために、2 次キャッシュを使用しています。putForExternalRead
デバッグすると、Book インスタンスとコレクション内の各作成者に対して発生していることがわかります。しかし、find(Book.class, ISBN)
メソッドを再度呼び出すと、著者のコレクションがデータベースから毎回取得される間、本のためだけにキャッシュが使用されます。作成者のコレクションが二次キャッシュに入れられるたびに。コレクションのキャッシュ アクセス戦略を変更する必要がある場合はお知らせください。Jboss 6.0 Infinispan 5 と postgres 9 DBMS を使用しています。
これが私のコードです
package bookentity.ejb;
/* * このテンプレートを変更するには、[ツール] | [ツール] を選択します。テンプレート * エディターでテンプレートを開きます。*/
import java.io.Serializable;
import java.util.ArrayList;
import javax.persistence.Cacheable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.ManyToMany;
import javax.persistence.JoinTable;
//import javax.persistence.JoinColumns;
import javax.persistence.JoinColumn;
import java.util.Collection;
import java.util.List;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
//import javax.persistence.inv
import javax.persistence.OneToMany;
@Entity
@Cacheable
@Table(name = "BOOK")
@NamedQueries({@NamedQuery(name="findBookByAuthorName",query="SELECT b FROM Book b, Author a WHERE a.authorName=:authorName AND b = SOME(SELECT x FROM a.books x)"),
@NamedQuery(name="findBookByTitle",query="SELECT b FROM Book b WHERE b.title=:bTitle")})
public class Book implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private int ISBN;
private String title;
private String description;
private Author author;
// @ManyToMany(fetch=FetchType.LAZY)
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(name="BOOK_AUTHOR", joinColumns=@JoinColumn(name="BOOK_ID"),
inverseJoinColumns=@JoinColumn(name="AUTHOR_ID"))
private Collection<Author> authors;
//@OneToMany(fetch=FetchType.EAGER, mappedBy="bookEntity")
@OneToMany(fetch=FetchType.LAZY, mappedBy="bookEntity")
public Collection<Review> reviews;
public Book() {
authors = new ArrayList<Author>();
reviews = new ArrayList<Review>();
}
public int getISBN() {
return ISBN;
}
public void setISBN(int ISBN) {
this.ISBN = ISBN;
}
public String getTitle(){
return title;
}
public void setTitle(String title){
this.title = title;
}
public String getDescription(){
return description;
}
public void setDescription(String description){
this.description = description;
}
public void addReview(Review review){
if(!getReviews().contains(review)){
getReviews().add(review);
if(review.getBookEntity()!=null){
review.getBookEntity().getReviews().remove(this);
}
review.setBookEntity(this);
}
}
public void addAuthor(Author author){
if (!getAuthors().contains(author)){
getAuthors().add(author);
}
if(!author.getBooks().contains(this)){
author.getBooks().add(this);
}
}
public Collection<Review> getReviews(){
return reviews;
}
public Collection<Author> getAuthors(){
return authors;
}
void setAuhorId(int authorID) {
}
}
Author Entityのコードは次のとおりです
package bookentity.ejb;
import java.io.Serializable;
import java.util.ArrayList;
import javax.persistence.Cacheable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import java.util.Collection;
import java.util.Hashtable;
import java.util.List;
import javax.naming.Context;
import javax.naming.InitialContext;
@Entity
@Cacheable
public class Author implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private int author_id;
String authorName;
String authAddress;
@ManyToMany(mappedBy = "authors")
private Collection<Book> books;
public Author() {
books = new ArrayList<Book>();
}
public void setAuthor_id(int author_id) {
this.author_id = author_id;
}
public int getAuthorId() {
return this.author_id;
}
public void setAuthorName(String authorName) {
this.authorName = authorName;
}
public String getAuthorName() {
return authorName;
}
public String getAuthorAddress(){
return this.authAddress;
}
public void setAuthorAddress(String authAddress){
this.authAddress = authAddress;
}
public Collection<Book> getBooks() {
return books;
}
public void addBook(Book book){
if(!getBooks().contains(book)) {
getBooks().add(book);
//book.getAuthors().add(this);
}
if (!book.getAuthors().contains(this)){
book.getAuthors().add(this);
}
}
}
これがpersistence.xmlファイルです
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/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_1_0.xsd"
version="1.0">
<persistence-unit name="BookAuthorApp3-ejbPU" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/PostgresDS</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
<property name="hibernate.session_factory_name" value="SessionFactories/infinispan1" />
<property name="javax.persistence.sharedCache.mode" value="ALL" />
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_query_cache" value="true" />
<property name="hibernate.cacheable" value="true" />
<property name="hibernate.cache.use_structured_entries" value="true" />
<property name="hibernate.cache.infinispan.collection.cfg" value="entity" />
<property name="hibernate.cache.infinispan.bookentity.ej.Book.cfg" value="Books"/>
<property name="hibernate.cache.infinispan.bookentity.ej.Book.authors.cfg" value="Authors"/>
<property name="hibernate.cache.infinispan.statistics" value="true"/>
<property name="hibernate.generate_statistics" value="true" />
<property name="hibernate.cache.region_prefix" value="infinispan" />
<property name="hibernate.cache.infinispan.entity.cfg" value="entity" />
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.infinispan.JndiInfinispanRegionFactory" />
<property name="hibernate.cache.infinispan.cachemanager" value="java:CacheManager/entity" />
</properties>
これが infinispan-configs.xml ファイルです
<infinispan-config name="hibernate" jndi-name="java:CacheManager/entity">
<infinispan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:5.0 http://www.infinispan.org/schemas/infinispan-config-5.0.xsd"
xmlns="urn:infinispan:config:5.0">
<global>
<transport clusterName="${jboss.partition.name:DefaultPartition}-Hibernate" distributedSyncTimeout="17500">
<properties>
<property name="stack" value="${jboss.default.jgroups.stack:udp}"/>
</properties>
</transport>
<globalJmxStatistics enabled="true"/>
<shutdown hookBehavior="DONT_REGISTER"/>
</global>
<default>
<jmxStatistics enabled="false"/>
<!--transaction transactionManagerLookupClass="org.infinispan.transaction.lookup.JBossTransactionManagerLookup"/-->
</default>
<namedCache name="entity">
<clustering mode="invalidation">
<stateRetrieval fetchInMemoryState="false" timeout="20000"/>
<sync replTimeout="20000"/>
</clustering>
<locking isolationLevel="READ_COMMITTED" concurrencyLevel="1000"
lockAcquisitionTimeout="15000" useLockStriping="false" />
<eviction wakeUpInterval="5000" maxEntries="10000" strategy="LRU"/>
<expiration lifespan = "-1" maxIdle="-1"/>
<lazyDeserialization enabled="true"/>
</namedCache>