Hibernate Collection 缓存:如何使用?

问题描述 投票:0回答:2

我有两个实体:书籍和作者。本书有作者的集合。我正在使用二级缓存来保留 Book 实体及其作者。调试时,我可以看到 Book 实例和集合中的每个作者都发生了

putForExternalRead
。但是当我再次调用
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) {

    }


}

这是作者实体的代码

  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>
hibernate collections second-level-cache infinispan
2个回答
6
投票

集合本身必须使用

@Cache
注释进行缓存。请参阅文档

Hibernate 还允许您缓存集合的内容或标识符(如果集合包含其他实体)。在集合属性上使用@Cache注释。

示例 21.6。使用注释缓存集合

@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name="CUST_ID")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public SortedSet<Ticket> getTickets() {
    return tickets;
}

0
投票

在 jboss eap 7.3 上,我还需要添加到 persistence.xml 以使 infinispan 工作:

<property name="hibernate.ejb.classcache.bookentity.ej.Book" value="read-write"/>
<property name="hibernate.ejb.collectioncache.bookentity.ej.Book.authors" value="read-write"/>
© www.soinside.com 2019 - 2024. All rights reserved.