-->
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: EhCache queries are MUCH slower than not using cache
PostPosted: Wed Oct 15, 2008 10:21 am 
Newbie

Joined: Wed Oct 15, 2008 4:46 am
Posts: 2
Hi.
I'm trying to use EhCache, and it is really slow, much slower than not using cache.
I use the following classes:

Code:
@SuppressWarnings("serial")
@Entity
@Table(name="EMPLOYEE")
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY)

public class Employee {
   
   private int id;
   private String firstName;
   private String lastName;
   private Country country;
   private Set<Language> languages;
   
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   @Column(name="EMPLOYEE_ID")
   public int getId() {
      return id;
   }
   public void setId(int id) {
      this.id = id;
   }
   
   @Column(name="FIRST_NAME")
   public String getFirstName() {
      return firstName;
   }
   public void setFirstName(String firstName) {
      this.firstName = firstName;
   }
   
   @Column(name="LAST_NAME")
   public String getLastName() {
      return lastName;
   }
   public void setLastName(String lastName) {
      this.lastName = lastName;
   }
   
   @ManyToOne
   @JoinColumn(name="COUNTRY")
   @Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
   @Cascade(org.hibernate.annotations.CascadeType.ALL)
   public Country getCountry() {
      return country;
   }
   public void setCountry(Country country) {
      this.country = country;
   }
   
   @ManyToMany(fetch=FetchType.EAGER)
   @JoinTable(joinColumns={@JoinColumn(name="EMPLOYEE_ID")},
         inverseJoinColumns={@JoinColumn(name="LANGUAGE_ID")})
   @Cache(usage=CacheConcurrencyStrategy.READ_ONLY)
   public Set<Language> getLanguages() {
      return languages;
   }
   public void setLanguages(Set<Language> languages) {
      this.languages = languages;
   }
   
   
   public boolean equals(Object obj) {
      if (this == obj)
         return true;
      if ((obj == null) || (obj.getClass() != this.getClass()))
         return false;
      // object must be Player at this point
      Employee test = (Employee) obj;
      boolean result =  this.id == test.id;
      return result;
   }
   
   public int hashCode() {
      return this.id;
   }


Code:
@SuppressWarnings("serial")
@Entity
@Table(name="country")
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY)

public class Country {
   
   private int id;
   private String name;
   private String printableName;
   private String iso3;
   private String iso;
   private Set<Employee> employees;
   
   
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   @Column(name="NUMCODE")
   public int getId() {
      return id;
   }
   public void setId(int id) {
      this.id = id;
   }
   @Column(name="name")
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   
   @Column(name="printable_name")
   public String getPrintableName() {
      return printableName;
   }
   public void setPrintableName(String printableName) {
      this.printableName = printableName;
   }
   
   @Column(name="iso")
   public String getIso() {
      return iso;
   }
   public void setIso(String iso) {
      this.iso = iso;
   }

   @Column(name="iso3")
   public String getIso3() {
      return iso3;
   }
   public void setIso3(String iso3) {
      this.iso3 = iso3;
   }
   
   public boolean equals(Object obj) {
      if (this == obj)
         return true;
      if ((obj == null) || (obj.getClass() != this.getClass()))
         return false;
      // object must be Player at this point
      Country test = (Country) obj;
      boolean result =  this.id == test.id;
      return result;
   }
   
   public int hashCode() {
      return this.id;
   }
   
   @OneToMany(targetEntity=Employee.class, mappedBy="country")
   public Set<Employee> getEmployees() {
      return employees;
   }
   public void setEmployees(Set<Employee> employees) {
      this.employees = employees;
   }


Code:
@SuppressWarnings("serial")
@Entity
@Table(name="LANGUAGE")
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY)

public class Language {

   private int id;
   private String name;
   private Set<Employee> employees;
   
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   @Column(name="LANGUAGE_ID")
   public int getId() {
      return id;
   }
   public void setId(int id) {
      this.id = id;
   }
   
   @Column(name="NAME")
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   
   public boolean equals(Object obj) {
      if (this == obj)
         return true;
      if ((obj == null) || (obj.getClass() != this.getClass()))
         return false;
      // object must be Player at this point
      Language test = (Language) obj;
      boolean result =  this.id == test.id;
      return result;
   }
   
   public int hashCode() {
      return this.id;
   }

   
   @ManyToMany(mappedBy="languages")
   public Set<Employee> getEmployees() {
      return employees;
   }
   public void setEmployees(Set<Employee> employees) {
      this.employees = employees;
   }


I'm using Hibernate version: 3.2.5 MySQL 6
The code that I use:
Code:
         HibernateUtil.init();
         long t0 = System.currentTimeMillis();
         for(int i = 0; i < 500; i++) {
            Session session = HibernateUtil.getSession();
            Transaction tx = session.beginTransaction();
            List l = null;
            l = session.createQuery("from Employee e where e.country=28").list();               
            tx.commit();
         }
         long t1 = System.currentTimeMillis();
         System.out.println("Elapsed time = " + (t1 - t0) + " ms.");




The generated SQL:
Hibernate: select employee0_.EMPLOYEE_ID as EMPLOYEE1_55_, employee0_.COUNTRY as COUNTRY55_, employee0_.FIRST_NAME as FIRST2_55_, employee0_.LAST_NAME as LAST3_55_ from EMPLOYEE employee0_ where employee0_.COUNTRY=28

Hibernate: select country0_.NUMCODE as NUMCODE56_0_, country0_.iso as iso56_0_, country0_.iso3 as iso3_56_0_, country0_.name as name56_0_, country0_.printable_name as printable5_56_0_ from country country0_ where country0_.NUMCODE=?

Hibernate: select languages0_.EMPLOYEE_ID as EMPLOYEE1_1_, languages0_.LANGUAGE_ID as LANGUAGE2_1_, language1_.LANGUAGE_ID as LANGUAGE1_54_0_, language1_.NAME as NAME54_0_ from EMPLOYEE_LANGUAGE languages0_ left outer join LANGUAGE language1_ on languages0_.LANGUAGE_ID=language1_.LANGUAGE_ID where languages0_.EMPLOYEE_ID=?

These queries are used only for the 1st iteration of the loop. After that all entities are found in the cache.

Debug level Hibernate log excerpt:

15 Oct 2008 16:09:57,713 DEBUG EhCache:77 - key: com.BPIntech.playSPEX.core.businessLogic.entities.real.Country#28
15 Oct 2008 16:09:57,714 DEBUG MemoryStore:135 - com.BPIntech.playSPEX.core.businessLogic.entities.real.CountryCache: com.BPIntech.playSPEX.core.businessLogic.entities.real.CountryMemoryStore hit for com.BPIntech.playSPEX.core.businessLogic.entities.real.Country#28
15 Oct 2008 16:09:57,716 DEBUG EhCache:77 - key: com.BPIntech.playSPEX.core.businessLogic.entities.real.Employee.languages#3949
15 Oct 2008 16:09:57,717 DEBUG MemoryStore:135 - com.BPIntech.playSPEX.core.businessLogic.entities.real.Employee.languagesCache: com.BPIntech.playSPEX.core.businessLogic.entities.real.Employee.languagesMemoryStore hit for com.BPIntech.playSPEX.core.businessLogic.entities.real.Employee.languages#3949
15 Oct 2008 16:09:57,717 DEBUG EhCache:77 - key: com.BPIntech.playSPEX.core.businessLogic.entities.real.Language#17
15 Oct 2008 16:09:57,723 DEBUG MemoryStore:135 - com.BPIntech.playSPEX.core.businessLogic.entities.real.LanguageCache: com.BPIntech.playSPEX.core.businessLogic.entities.real.LanguageMemoryStore hit for com.BPIntech.playSPEX.core.businessLogic.entities.real.Language#17
15 Oct 2008 16:09:57,724 DEBUG EhCache:77 - key: com.BPIntech.playSPEX.core.businessLogic.entities.real.Language#16
15 Oct 2008 16:09:57,724 DEBUG MemoryStore:135 - com.BPIntech.playSPEX.core.businessLogic.entities.real.LanguageCache: com.BPIntech.playSPEX.core.businessLogic.entities.real.LanguageMemoryStore hit for com.BPIntech.playSPEX.core.businessLogic.entities.real.Language#16
15 Oct 2008 16:09:57,726 DEBUG EhCache:77 - key: com.BPIntech.playSPEX.core.businessLogic.entities.real.Language#9
15 Oct 2008 16:09:57,727 DEBUG MemoryStore:135 - com.BPIntech.playSPEX.core.businessLogic.entities.real.LanguageCache: com.BPIntech.playSPEX.core.businessLogic.entities.real.LanguageMemoryStore hit for com.BPIntech.playSPEX.core.businessLogic.entities.real.Language#9

continued by many more ...


Hibernate Configuration:
hibernate.connection.url = jdbc:mysql://localhost/testing?autoReconnect=true
hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
hibernate.connection.pool_size = 3
hibernate.current_session_context_class = thread
hibernate.connection.autocommit = false
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=1800
hibernate.c3p0.max_statements=50
# hibernate 2nd cache
hibernate.cache.use_second_level_cache=true
hibernate.cache.provider_class=net.sf.ehcache.hibernate.SingletonEhCacheProvider
net.sf.ehcache.configurationResourceName=/ehcache2.xml
hibernate.cache.use_query_cache=true

EhCache configuration:
<defaultCache
maxElementsInMemory="50000"
eternal="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>

<cache name="com.BPIntech.playSPEX.core.businessLogic.entities.real.Employee"
maxElementsInMemory="5000"
eternal="true"
overflowToDisk="false"
/>

<cache name="com.BPIntech.playSPEX.core.businessLogic.entities.real.Language"
maxElementsInMemory="100"
eternal="true"
overflowToDisk="false"
/>
<cache name="com.BPIntech.playSPEX.core.businessLogic.entities.real.Country"
maxElementsInMemory="500"
eternal="true"
overflowToDisk="false"
/>
<cache name="com.BPIntech.playSPEX.core.businessLogic.entities.real.Employee.languages"
maxElementsInMemory="40000"
eternal="true"
overflowToDisk="false"
/>
<cache name="com.BPIntech.playSPEX.core.businessLogic.entities.real.Employee.country"
maxElementsInMemory="5000"
eternal="true"
overflowToDisk="false"
/>

<cache name="org.hibernate.cache.StandardQueryCache"
maxElementsInMemory="5000"
eternal="true"
timeToLiveSeconds="120"
overflowToDisk="false"
/>
<cache name="org.hibernate.cache.UpdateTimestampsCache"
maxElementsInMemory="50000"
eternal="true"
overflowToDisk="false"
/>


Any would be highly appreciated.

Regards,

Amir[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 16, 2008 9:04 am 
Newbie

Joined: Wed Oct 15, 2008 4:46 am
Posts: 2
I disabled Hibernate logging, and now EhCache is much faster not using cache.


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.