二级缓存demo实例,hibernate延迟加载org

public static void main(String[] args) {
 
  DeptEntity dept = getDept(“402882e762ae888d0162ae888e420000”);

转载:

延迟加载在Hibernate中是默认延迟加载;

  //dept.getEmp()得到子表的记录集合
  System.out.println(dept.getEmp());

hibernate使用版本是:hibernate-release-4.3.4.Final

测试代码一:

}

需要的jar包:hibernate-release-4.3.4Final\lib\required下所有jar包

HibernateTest.java

private static DeptEntity getDept(String did){
  Session session = sessionFactory.openSession();
  DeptEntity dept = (DeptEntity)session.get(DeptEntity.class, did);
  session.close();
  return dept;
}

ehcache 
jar包:hibernate-release-4.3.4.Final\lib\optional\ehcache下所有包

代码:

 

junit:junit-4.10.jar和mysql-connector-java-5.1.15-bin.jar

/**
 *
 */
package com.b510.examples;

运行结果:

注:hibernate
4.2.5版本ehcache缓存不依赖commons-logging-1.1.1.jar,需要的是slf4j-api-1.6.1.jar

import java.util.Set;

Exception in thread “main” org.hibernate.LazyInitializationException:
failed to lazily initialize a collection of role:
com.javakc.hibernate.onetomany.entity.DeptEntity.emp, could not
initialize proxy – no Session
at
org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:566)
at
org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:186)
at
org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:545)
at
org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:124)
at
org.hibernate.collection.internal.PersistentSet.toString(PersistentSet.java:326)
at java.lang.String.valueOf(String.java:2827)
at java.io.PrintStream.println(PrintStream.java:771)
at
com.javakc.hibernate.onetomany.action.TestAction.main(TestAction.java:74)

项目结构如下
 
图片 1
 

import org.hibernate.Session;

 

hibernate.cfg.xml

/**
 *
 * @author XHW
 *
 * @date 2011-7-18
 *
 */
public class HibernateTest {
 public static void main(String[] args) {
  new HibernateTest().update();
 }
 public void update(){
  Session
session=HibernateSessionFactoryUtil.getSessionFactory().getCurrentSession();
  session.beginTransaction();
  Category
category=(Category)session.get(Category.class, 1);
  System.out.println(“id:”+category.getId()+” 
,name:”+category.getName()+”,
description:”+category.getDescription());
  
  Set<Product>
products=category.getProducts();
  
  session.getTransaction().commit();  
 }
 
 
}

集合延迟加载初始化失败,不能初始化一个代理。就是集合在非一对一对象关系中,为了节省资源是默认延迟加载,而get方法又是非延迟加载,所以在执行完一次数据库查询后就执行session.close();关闭了session,而集合是延迟加载,在使用集合时再加载,此时session已经关闭,所以得不到代理。解决方法:可以在主表的hbm配置文件中,在<set>标签里设置lazy=”false”,集合就不延迟加载了,因此在执行get方法时,集合也获取到了,就不会出现延迟加载问题了。

  1. <?xml version=’1.0′ encoding=’utf-8′?>  
  2. <!DOCTYPE hibernate-configuration PUBLIC  
  3.         “-//Hibernate/Hibernate Configuration DTD 3.0//EN”  
  4.         “;  
  5. <hibernate-configuration>  
  6.     <session-factory>  
  7.         <!– Database connection settings –>  
  8.         <property name=”connection.driver_class”>com.mysql.jdbc.Driver</property>  
  9.         <property name=”connection.url”>jdbc:mysql://127.0.0.1:3306/hibernate4</property>  
  10.         <property name=”connection.username”>root</property>  
  11.         <property name=”connection.password”>root</property>  
  12.         <!– JDBC connection pool (use the built-in) –>  
  13.         <property name=”connection.pool_size”>1</property>  
  14.         <!– SQL dialect –>  
  15.         <property name=”dialect”>org.hibernate.dialect.MySQL5Dialect</property>  
  16.         <!– Enable Hibernate’s automatic session context management –>  
  17.         <property name=”current_session_context_class”>thread</property>  
  18.         <!– Disable the second-level cache –>  
  19.         <!–<property name=”cache.provider_class”>org.hibernate.cache.internal.NoCacheProvider</property> 
  20.         –>  
  21.         <!– 配置二级缓存 –>  
  22.         <property name=”hibernate.cache.use_second_level_cache”>true</property>  
  23.         <property name=”hibernate.cache.region.factory_class”>org.hibernate.cache.ehcache.EhCacheRegionFactory</property>  
  24.         <!– hibernate3的二级缓存配置 –>  
  25.         <!– <property name=”hibernate.cache.provider_class”>org.hibernate.cache.EhCacheProvider</property> –>  
  26.         <!– 开启查询缓存 –>  
  27.         <property name=”hibernate.cache.use_query_cache”>true</property>  
  28.           
  29.         <!– Echo all executed SQL to stdout –>  
  30.         <property name=”show_sql”>true</property>  
  31.         <!– Drop and re-create the database schema on startup –>  
  32.         <property name=”hbm2ddl.auto”>update</property>  
  33.         <mapping class=”com.test.pojo.User” />  
  34.     </session-factory>  
  35. </hibernate-configuration>  

运行结果:

 

log4j:WARN No appenders could be found for logger
(org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
Hibernate:
    select
        category0_.id as id1_0_,
        category0_.name as name1_0_,
        category0_.description as descript3_1_0_
    from
        users.category category0_
    where
        category0_.id=?
id:1  ,name:java,
description:java好啊

注意:hibernate4和hibernate3配置不一样,hibernate4是

这里我们看到我们关心的是id,name和description属性,

  1. <property name=”hibernate.cache.region.factory_class”>org.hibernate.cache.ehcache.EhCacheRegionFactory</property>  

虽然有:  Set<Product>
products=category.getProducts();
代码,即:不处理集合对象。但是我们只要的是:

 

  System.out.println(“id:”+category.getId()+” 
,name:”+category.getName()+”,
description:”+category.getDescription());
输出的是id,name和description属性值,其他的我们不管,所以Hibernate用了lazy
loading(延迟加载),带来的好处就是我们不关心的

而hibernate3的配置是

数据,不用现在加载,当我们要用的时候,才去加载

  1. <property name=”hibernate.cache.provider_class”>org.hibernate.cache.EhCacheProvider</property>  

测试代码二:

 此处有一个疑问是:hibernate4的官方文档中,已经把class改了,但是属性名称没有改,还是
hibernate.cache.provider_class,不是上面的
hibernate.cache.region.factory_class,但是写成hibernate.cache.provider_class会
报下面错误

HibernateTest.java

 

代码:

Java代码 

/**
 *
 */
package com.b510.examples;

  1. org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.spi.CacheImplementor]  
  2.     at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:186)  
  3.     at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:150)  
  4.     at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:131)  
  5.     at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:264)  
  6.     at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1790)  
  7.     at com.test.pojo.UserTest.beforeClass(UserTest.java:28)  
  8.     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
  9.     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)  
  10.     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)  
  11.     at java.lang.reflect.Method.invoke(Method.java:597)  
  12.     at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)  
  13.     at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)  
  14.     at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)  
  15.     at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)  
  16.     at org.junit.runners.ParentRunner.run(ParentRunner.java:300)  
  17.     at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)  
  18.     at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)  
  19.     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)  
  20.     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)  
  21.     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)  
  22.     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)  
  23. Caused by: org.hibernate.cache.NoCacheRegionFactoryAvailableException: Second-level cache is used in the application, but property hibernate.cache.region.factory_class is not given, please either disable second level cache or set correct region factory class name to property hibernate.cache.region.factory_class (and make sure the second level cache provider, hibernate-infinispan, for example, is available in the classpath).  
  24.     at org.hibernate.cache.internal.NoCachingRegionFactory.buildTimestampsRegion(NoCachingRegionFactory.java:87)  
  25.     at org.hibernate.cache.spi.UpdateTimestampsCache.<init>(UpdateTimestampsCache.java:62)  
  26.     at org.hibernate.internal.CacheImpl.<init>(CacheImpl.java:72)  
  27.     at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:40)  
  28.     at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:35)  
  29.     at org.hibernate.service.internal.SessionFactoryServiceRegistryImpl.initiateService(SessionFactoryServiceRegistryImpl.java:91)  
  30.     at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:176)  
  31.     … 20 more  

import java.util.Set;

 说是hibernate.cache.region.factory_class属性没有配置,估计官方文档里没有把属性改过来。。。

import org.hibernate.Session;

 

/**
 *
 * @author XHW
 *
 * @date 2011-7-18
 *
 */
public class HibernateTest {
 public static void main(String[] args) {
  new HibernateTest().update();
 }
 public void update(){
  Session
session=HibernateSessionFactoryUtil.getSessionFactory().getCurrentSession();
  session.beginTransaction();
  Category category=(Category)session.get(Category.class, 1);
  System.out.println(“id:”+category.getId()+” 
,name:”+category.getName()+”,
description:”+category.getDescription());
  
  Set<Product> products=category.getProducts();
  for(Product product:products){
   System.out.println(“ID:  “+product.getId()+” 
name:”+product.getName()+” price: “+product.getPrice());
  }  
  session.getTransaction().commit();  
 }
 
 
}

ehcache.xml

运行效果:

  1. <?xml version=”1.0″ encoding=”UTF-8″?>  
  2. <ehcache xmlns:xsi=””  
  3.     xsi:noNamespaceSchemaLocation=””  
  4.     updateCheck=”false”>  
  5.     <!–  
  6.         name:cache唯一标识   
  7.         eternal:缓存是否永久有效   
  8.         maxElementsInMemory:内存中最大缓存对象数  
  9.         overflowToDisk(true,false):缓存对象达到最大数后,将缓存写到硬盘中  
  10.         diskPersistent:硬盘持久化  
  11.         timeToIdleSeconds:缓存清除时间   
  12.         timeToLiveSeconds:缓存存活时间  
  13.         memoryStoreEvictionPolicy:缓存清空策略  
  14.         1.FIFO:first in first out 先讲先出  
  15.         2.LFU: Less Frequently Used 一直以来最少被使用的  
  16.         3.LRU:Least Recently Used  最近最少使用的  
  17.     –>  
  18.     <defaultCache maxElementsInMemory=”1000″ eternal=”false”  
  19.         timeToIdleSeconds=”120″ timeToLiveSeconds=”120″ overflowToDisk=”true” />  
  20.     <cache name=”userCache” eternal=”false” maxElementsInMemory=”1000″  
  21.         overflowToDisk=”false” diskPersistent=”false” timeToIdleSeconds=”3600″  
  22.         timeToLiveSeconds=”3600″ memoryStoreEvictionPolicy=”LFU” />  
  23. </ehcache>  

log4j:WARN No appenders could be found for logger
(org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
Hibernate:
    select
        category0_.id as id1_0_,
        category0_.name as name1_0_,
        category0_.description as descript3_1_0_
    from
        users.category category0_
    where
        category0_.id=?
id:1  ,name:java, description:java好啊
Hibernate: 
    select
        products0_.category_id as
category2_1_,
        products0_.id as id1_,
        products0_.id as
id0_0_,
        products0_.category_id as
category2_0_0_,
        products0_.name as
name0_0_,
        products0_.price as
price0_0_,
        products0_.descripton as
descripton0_0_
    from
        users.product products0_

 

    where
       
products0_.category_id=?
ID:  1  name:java SE应用程序设计 price: 78.00
这里可以明确的告诉我们,当我们要加载Set集合的时候,这时候才去加载,而上面的例子,说明的是我们不加载的时候

User实体类

Hibernate就延迟加载

  1. package com.test.pojo;  
  2.   
  3. import javax.persistence.Entity;  
  4. import javax.persistence.GeneratedValue;  
  5. import javax.persistence.GenerationType;  
  6. import javax.persistence.Id;  
  7.   
  8. import org.hibernate.annotations.Cache;  
  9. import org.hibernate.annotations.CacheConcurrencyStrategy;  
  10.   
  11. @Entity  
  12. @Cache(usage=CacheConcurrencyStrategy.READ_WRITE)  
  13. public class User {  
  14.     @Id  
  15.     @GeneratedValue(strategy=GenerationType.IDENTITY)  
  16.     private int id;  
  17.     private String name;  
  18.     private int age;  
  19.     public int getId() {  
  20.         return id;  
  21.     }  
  22.     public void setId(int id) {  
  23.         this.id = id;  
  24.     }  
  25.     public String getName() {  
  26.         return name;  
  27.     }  
  28.     public void setName(String name) {  
  29.         this.name = name;  
  30.     }  
  31.     public int getAge() {  
  32.         return age;  
  33.     }  
  34.     public void setAge(int age) {  
  35.         this.age = age;  
  36.     }  
  37.       
  38. }  

取消延迟加载:

 

Category.hbm.xml

UserTest测试类:

代码:

  1. package com.test.pojo;  
  2. import org.hibernate.HibernateException;  
  3. import org.hibernate.Session;  
  4. import org.hibernate.SessionFactory;  
  5. import org.hibernate.cfg.Configuration;  
  6. import org.hibernate.service.ServiceRegistry;  
  7. import org.hibernate.service.ServiceRegistryBuilder;  
  8. import org.junit.BeforeClass;  
  9. import org.junit.Test;  
  10.   
  11. public class UserTest {  
  12.       
  13.     private static SessionFactory sessionFactory = null;  
  14.     @BeforeClass  
  15.     public static void beforeClass() {  
  16.         Configuration configuration = new Configuration();  
  17.           
  18.   
  19.         try {  
  20.             configuration.configure();  
  21.         } catch (HibernateException e) {  
  22.             // TODO Auto-generated catch block  
  23.             e.printStackTrace();  
  24.         }  
  25.               
  26.           
  27.         ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();  
  28.         sessionFactory = configuration.buildSessionFactory(serviceRegistry);  
  29.     }   
  30.     @Test  
  31.     public void testEhcache() {  
  32.         Session session = sessionFactory.openSession();  
  33.         session.beginTransaction();  
  34.         User u1 = (User) session.load(User.class, 3);  
  35.         System.out.println(u1.getName());  
  36.         session.getTransaction().commit();  
  37.         session.close();  
  38.         Session session2 = sessionFactory.openSession();  
  39.           
  40.         session2.beginTransaction();  
  41.         User u2 = (User) session2.load(User.class, 3);  
  42.         System.out.println(u2.getName());  
  43.         session2.getTransaction().commit();  
  44.         session2.close();  
  45.     }  
  46. }  

<?xml version=”1.0″ encoding=”utf-8″?>
<!DOCTYPE hibernate-mapping PUBLIC “-//Hibernate/Hibernate Mapping
DTD 3.0//EN”
“”>
<!–
    Mapping file autogenerated by MyEclipse Persistence Tools
–>
<hibernate-mapping>
    <class name=”com.b510.examples.Category” table=”category”
catalog=”users”>
        <id name=”id” type=”java.lang.Integer”>
            <column name=”id” />
            <generator class=”increment” />
        </id>
        <property name=”name” type=”java.lang.String”>
            <column name=”name” length=”500″ />
        </property>
        <property name=”description” type=”java.lang.String”>
            <column name=”description” length=”500″ />
        </property>
        <set name=”products” inverse=”true” lazy=”false”>
            <key>
                <column name=”category_id” />
            </key>
            <one-to-many class=”com.b510.examples.Product” />
        </set>
    </class>
</hibernate-mapping>

 结果:

测试代码:

 

HIbernateTest.java

  1. Hibernate: select user0_.id as id1_0_0_, user0_.age as age2_0_0_, user0_.name as name3_0_0_ from User user0_ where user0_.id=?  
  2. zhangsan  
  3. zhangsan  

代码:

 

/**
 *
 */
package com.b510.examples;

list二级缓存测试

import java.util.Set;

  1. package com.test.pojo;  
  2. import java.util.List;  
  3.   
  4. import org.hibernate.HibernateException;  
  5. import org.hibernate.Session;  
  6. import org.hibernate.SessionFactory;  
  7. import org.hibernate.cfg.Configuration;  
  8. import org.hibernate.service.ServiceRegistry;  
  9. import org.hibernate.service.ServiceRegistryBuilder;  
  10. import org.junit.BeforeClass;  
  11. import org.junit.Test;  
  12.   
  13. public class UserTest {  
  14.       
  15.     private static SessionFactory sessionFactory = null;  
  16.     @BeforeClass  
  17.     public static void beforeClass() {  
  18.         Configuration configuration = new Configuration();  
  19.           
  20.   
  21.         try {  
  22.             configuration.configure();  
  23.         } catch (HibernateException e) {  
  24.             // TODO Auto-generated catch block  
  25.             e.printStackTrace();  
  26.         }  
  27.               
  28.           
  29.         ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();  
  30.         sessionFactory = configuration.buildSessionFactory(serviceRegistry);  
  31.     }   
  32.     @SuppressWarnings(“unchecked”)  
  33.     @Test  
  34.     public void testListEhcache() {  
  35.         Session session = sessionFactory.openSession();  
  36.         session.beginTransaction();  
  37.         List<User> users1 = (List<User>)session.createQuery(“from User”).setCacheable(true).list();  
  38.         for(User user : users1) {  
  39.             System.out.println(user.getName());  
  40.         }  
  41.         session.getTransaction().commit();  
  42.         session.close();  
  43.           
  44.         Session session2 = sessionFactory.openSession();  
  45.         session2.beginTransaction();  
  46.         List<User> users2 = (List<User>)session2.createQuery(“from User”).setCacheable(true).list();  
  47.         for(User user : users2) {  
  48.             System.out.println(user.getName());  
  49.         }  
  50.         session2.getTransaction().commit();  
  51.         session2.close();  
  52.     }  
  53. }  

import org.hibernate.Session;

 输出结果:

/**
 *
 * @author XHW
 *
 * @date 2011-7-18
 *
 */
public class HibernateTest {
 public static void main(String[] args) {
  new HibernateTest().update();
 }
 public void update(){
  Session
session=HibernateSessionFactoryUtil.getSessionFactory().getCurrentSession();
  session.beginTransaction();
  Category category=(Category)session.get(Category.class, 1);
  System.out.println(“id:”+category.getId()+” 
,name:”+category.getName()+”,
description:”+category.getDescription());
  
  Set<Product> products=category.getProducts();
   
  session.getTransaction().commit();  
 }
 
 
}

  1. Hibernate: select user0_.id as id1_0_, user0_.age as age2_0_, user0_.name as name3_0_ from User user0_  
  2. zhangsan  
  3. zhangsan  
  4. lisi  
  5. wangwu  
  6. zhangsan  
  7. zhangsan  
  8. lisi  
  9. wangwu  

运行效果:

log4j:WARN No appenders could be found for logger
(org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
Hibernate:
    select
        category0_.id as id1_0_,
        category0_.name as name1_0_,
        category0_.description as descript3_1_0_
    from
        users.category category0_
    where
        category0_.id=?
Hibernate:
    select
        products0_.category_id as category2_1_,
        products0_.id as id1_,
        products0_.id as id0_0_,
        products0_.category_id as category2_0_0_,
        products0_.name as name0_0_,
        products0_.price as price0_0_,
        products0_.descripton as descripton0_0_
    from
        users.product products0_
    where
        products0_.category_id=?
id:1  ,name:java, description:java好啊
和测试代码一的运行结果相互比较,我们会发现,这次运行结果用了两条select语句。但是我们会发现

第二条select语句,对于我们的需求是没有必要的,他只有一个用处就是占用我们的程序执行时间。当然,

这是我们不希望看到的结果。

一般情况下,Hibernate会默认给我们设置延迟加载。lazy=”true”
,这样会提升我们的系统性能,所以一般情况下,我们不会去

设置lazy=”false”,当然在特殊的情况下,我们必须要取消延迟加载的时候,我们就把lazy=”false”,就可以了

Post Author: admin

发表评论

电子邮件地址不会被公开。 必填项已用*标注