如何缓存hibernate集合?

时间:2016-08-26 17:23:20

标签: java hibernate caching hibernate-mapping ehcache

我有两个实体 com.gn.entities.Report com.gn.entities.ReportSummary

 <?xml version="1.0"?>
 <!DOCTYPE hibernate-mapping PUBLIC  "-//Hibernate/Hibernate Mapping DTD z.0//EN"  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 <hibernate-mapping>
<class name="com.gn.entities.Report" table="REPORT" >
     <id name="id" type="int" column="id" >
             <generator class="native"/>
     </id>
     <property name="name">
           <column name="NAME" />
     </property>
     <set name="reportSummaryList" table="REPORT_SUMMARY" cascade="all" inverse="true" fetch="join" >
         <key column="RPT_ID" not-null="true"></key>
         <one-to-many class="com.gn.entities.ReportSummary"/>
     </set>
 </class>

 <?xml version="1.0"?>
 <!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.gn.entities.ReportSummary" table="REPORT_SUMMARY" >
    <composite-id name="id" class="com.gn.entities.ReportSummaryId">
         <key-property name="id" column="ID"></key-property>
         <key-many-to-one name="report" class="com.gn.entities.Report" column="RPT_ID"/>
    </composite-id>
    <property name="name">
         <column name="NAME" />
    </property>
</class>

  

我想知道

之间有什么区别

方案1:实体上的缓存标记并设置
<class name="com.gn.entities.Report" table="REPORT" > <cache usage="read-write" region="report"/>
<set name="reportSummaryList" table="REPORT_SUMMARY" cascade="all" inverse="true" fetch="join" > <cache usage="read-write" region="report"/>

  <?xml version="1.0"?>
  <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  <hibernate-mapping>
<class name="com.gn.entities.Report" table="REPORT" >
    <cache usage="read-write" region="report"/>
     <id name="id" type="int" column="id" >
             <generator class="native"/>
     </id>
     <property name="name">
           <column name="NAME" />
     </property>
     <set name="reportSummaryList" table="REPORT_SUMMARY" cascade="all" inverse="true" fetch="join" >
         <cache usage="read-write" region="report"/>
         <key column="RPT_ID" not-null="true"></key>
         <one-to-many class="com.gn.entities.ReportSummary"/>
     </set>
 </class>

方案2:仅在实体上设置缓存标记<cache usage="read-write" region="report"/>

 <?xml version="1.0"?>
 <!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 <hibernate-mapping>
<class name="com.gn.entities.Report" table="REPORT" >
    <cache usage="read-write" region="report"/>
     <id name="id" type="int" column="id" >
             <generator class="native"/>
     </id>
     <property name="name">
           <column name="NAME" />
     </property>
     <set name="reportSummaryList" table="REPORT_SUMMARY" cascade="all" inverse="true" fetch="join" >


   <!-- <cache usage="read-write" region="report"/>  -->

         <key column="RPT_ID" not-null="true"></key>
         <one-to-many class="com.gn.entities.ReportSummary"/>
     </set>
 </class>

  

问题1:在这两种情况下,Report和ReportSummary都会被缓存?如果是,那么使实体和集合可以缓存的用途是什么?

     

问题2:此外,是否提取影响缓存(fetch = join或fetch = select)?在两种情况下?

     <set name="reportSummaryList" table="REPORT_SUMMARY" cascade="all" inverse="true" fetch="join" >

     and
     <set name="reportSummaryList" table="REPORT_SUMMARY" cascade="all" inverse="true" fetch="select" >

更新: -

好的,这意味着我必须使 ReportSummary 也可以缓存。 完成后我发现我仍然收到如下日志消息: -

17:23:04,824 TRACE DefaultLoadEventListener:403 - 试图解决:[com.gn.entities.ReportSummary #component [id,report] {report = com.gn.entities.Report#1,id = 1}]

17:23:04,824 TRACE DefaultLoadEventListener:427 - 对象未在任何缓存中解析:[com.gn.entities.ReportSummary #component [id,report] {report = com.gn.entities.Report#1,id = 1}]

17:23:04,824 TRACE AbstractEntityPersister:3923 - 获取实体:[com.gn.entities.ReportSummary #component [id,report] {report = com.gn.entities.Report#1,id = 1}] 17:23:04,824 DEBUG Loader:2105 - 正在加载实体:[com.gn.entities.ReportSummary #component [id,report] {report = com.gn.entities.Report#1,id = 1}] 17:23:04,824 DEBUG SQL:104 -     / * load com.gn.entities.ReportSummary / select         reportsumm0_.ID为ID1_1_0_,         reportsumm0_.RPT_ID为RPT2_1_0_,         reportsumm0_.NAME为NAME3_1_0_     从         REPORT_SUMMARY reportsumm0_     哪里         reportsumm0_.ID =?         和reportsumm0_.RPT_ID =? 休眠:     / load com.gn.entities.ReportSummary * / select         reportsumm0_.ID为ID1_1_0_,         reportsumm0_.RPT_ID为RPT2_1_0_,         reportsumm0_.NAME为NAME3_1_0_     从         REPORT_SUMMARY reportsumm0_     哪里         reportsumm0_.ID =?         和reportsumm0_.RPT_ID =?

17:23:04,824 TRACE JdbcCoordinatorImpl:319 - 注册语句[com.mysql.jdbc.JDBC4PreparedStatement@e3c0e40:/ * load com.gn.entities.ReportSummary * / select reportsumm0_.ID as ID1_1_0_,reportsumm0_.RPT_ID as RPT2_1_0_ ,reportsumm0_.NAME为来自REPORT_SUMMARY的NAME3_1_0_ reportsumm0_其中reportsumm0_.ID = **未指定**和reportsumm0_.RPT_ID = **未指定] 17:23:04,824 TRACE JdbcCoordinatorImpl:329 - 注册最后一个查询语句[com.mysql.jdbc.JDBC4PreparedStatement@e3c0e40:/ * load com.gn.entities.ReportSummary * / select reportsumm0_.ID as ID1_1_0_,reportsumm0_.RPT_ID as RPT2_1_0_, reportsumm0_.NAME为来自REPORT_SUMMARY的NAME3_1_0_ reportsumm0_其中reportsumm0_.ID = 未指定**和reportsumm0_.RPT_ID = **未指定**]

  

这意味着hibernate找到了ReportSummary id并且它会命中   数据库使用该ID获取ReportSummary实体?

那么,如果有10000个ReportSummary实体,那么将有10000个数据库命中?

1 个答案:

答案 0 :(得分:0)

在任何一种情况下都不会缓存

ReportSummary个实例,因为您没有将该实体类标记为可缓存。

如果声明Report实体是可缓存的,那么显然Hibernate会将其实例缓存在二级缓存中。

如果reportSummaryList不可缓存,则无论Report是否可缓存,都不会缓存该集合。

如果reportSummaryList可缓存,则Hibernate会缓存ReportSummary中存在的reportSummaryList个实例的ID。 ReportSummary是否可缓存并不重要; ids缓存在单独的缓存条目中。但是,在这种情况下,您可能还希望使ReportSummary实体可缓存,以便在根据缓存集合条目中包含的ID读取其实例时提高性能。

更多详情herehere