-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Does not use second level cache when retrieving a collection
PostPosted: Sat Dec 29, 2012 7:12 am 
Newbie

Joined: Sat Dec 29, 2012 7:04 am
Posts: 1
I have two entities Book and Author. A book has a collection of authors. I am using second level cache to keep the book entity with its authors. When debugging I can see there is putForExternalRead is happening for Book instance and each author in collection. But when I am calling find(Book.class, ISBN) method again it is using cache just for book while the collection of authors is retrieved each time from database. Each time collection of authors are put in second level cache. Please let me know if there is some where I need to change cache access strategy for collection. I am using Jboss 6.0 Infinispan 5. and postgres 9 DBMS.


Here is my code

Code:
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) {

    }


}


Here is my code for Author Entity

Code:
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);
  }
}

}


Here is the persistence.xml file

Code:
<?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>


Here is infinispan-configs.xml file
Code:
<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>


Top
 Profile  
 
 Post subject: Re: Does not use second level cache when retrieving a collection
PostPosted: Wed Jan 02, 2013 3:02 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Looking at your annotations it seems that you aren't caching into 2L-Cache the collection at all,
because the according annotation on your collection is missing:


Code:
...
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(name="BOOK_AUTHOR", joinColumns=@JoinColumn(name="BOOK_ID"),
inverseJoinColumns=@JoinColumn(name="AUTHOR_ID"))
private Collection<Author> authors;
...


if you want cache the collection:


Code:
...
@ManyToMany(fetch=FetchType.EAGER)
@Cacheable
@JoinTable(name="BOOK_AUTHOR", joinColumns=@JoinColumn(name="BOOK_ID"),
inverseJoinColumns=@JoinColumn(name="AUTHOR_ID"))
private Collection<Author> authors;
...


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.