【问题标题】:How to cache hibernate collection?如何缓存休眠集合?
【发布时间】:2017-01-03 10:38:24
【问题描述】:

我有两个实体 com.gn.entities.Reportcom.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:仅在实体上缓存标记 (&lt;cache usage="read-write" region="report"/&gt;)

 <?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 调试 SQL:104 - /* 加载 com.gn.entities.ReportSummary /select 报告summ0_.ID为ID1_1_0_, 报告summ0_.RPT_ID为RPT2_1_0_, 报告summ0_.NAME 为 NAME3_1_0_ 从 REPORT_SUMMARY 报告summ0_ 在哪里 报告summ0_.ID=? 并报告summ0_.RPT_ID=? 休眠: / 加载 com.gn.entities.ReportSummary */ 选择 报告summ0_.ID为ID1_1_0_, 报告summ0_.RPT_ID为RPT2_1_0_, 报告summ0_.NAME 为 NAME3_1_0_ 从 REPORT_SUMMARY 报告summ0_ 在哪里 报告summ0_.ID=? 并报告summ0_.RPT_ID=?

17:23:04,824 TRACE JdbcCoordinatorImpl:319 - 注册语句 [com.mysql.jdbc.JDBC4PreparedStatement@e3c0e40: /* 加载 com.gn.entities.ReportSummary */ 选择 reportsumm0_.ID 作为 ID1_1_0_,reportsumm0_.RPT_ID 作为 RPT2_1_0_ ,reportsumm0_.NAME 为 NAME3_1_0_ 从 REPORT_SUMMARY 报告summ0_ where reportssumm0_.ID=** NOT SPECIFIED ** and reportssumm0_.RPT_ID=** NOT SPECIFIED ] 17:23:04,824 TRACE JdbcCoordinatorImpl:329 - 注册最后一个查询语句 [com.mysql.jdbc.JDBC4PreparedStatement@e3c0e40: /* 加载 com.gn.entities.ReportSummary */ 选择 reportsumm0_.ID 作为 ID1_1_0_,reportsumm0_.RPT_ID 作为 RPT2_1_0_,从 REPORT_SUMMARY 中以 NAME3_1_0_ 的形式报告summ0_.NAME 报告summ0_ where reportssumm0_.ID= NOT SPECIFIED ** and reportssumm0_.RPT_ID=** NOT SPECIFIED **]

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

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

【问题讨论】:

    标签: java hibernate caching hibernate-mapping ehcache


    【解决方案1】:

    ReportSummary 实例在这两种情况下都不会被缓存,因为您没有将该实体类标记为可缓存。

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

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

    如果reportSummaryList 是可缓存的,那么Hibernate 会缓存reportSummaryList 中存在的ReportSummary 实例的ID。 ReportSummary 是否可缓存无关紧要; id 缓存在单独的缓存条目中。但是,在这种情况下,您可能还希望使 ReportSummary 实体可缓存,以便在基于缓存集合条目中包含的 id 读取其实例时提高性能。

    更多详情herehere

    【讨论】:

    • 感谢您的快速回复,我已经更新了我的问题。请您对此发表评论。
    • 查看抓取计划和抓取策略以优化加载。关于缓存,如果实体实例在缓存中,则不会从数据库中加载。第一次显然必须加载。此外,请检查我提供的链接和其他有关 L2 缓存的文档,以便能够确定实体是否适合缓存。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-19
    • 2016-08-13
    • 2010-11-24
    相关资源
    最近更新 更多