Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 即使lazy=true,集合仍被急切地加载?_Java_Hibernate_Lazy Loading_Hibernate Mapping - Fatal编程技术网

Java 即使lazy=true,集合仍被急切地加载?

Java 即使lazy=true,集合仍被急切地加载?,java,hibernate,lazy-loading,hibernate-mapping,Java,Hibernate,Lazy Loading,Hibernate Mapping,我遇到了一个关于Hibernate延迟加载的问题。我在Hibernate论坛上发布了这篇文章,但没有收到任何回复,所以我想也许stackoverflow上的各位可以帮我一把。帖子链接是: 我正在复制以下内容,提前感谢: 问题是我试图延迟加载一个集合,但它总是被急切地加载,这对我的应用程序性能产生了巨大的影响。这里是场景,我描述了涉及的3个类的模型: 冠军:有一个联赛冠军有一个默认联赛 联盟:有许多竞争对手-属于一个锦标赛许多联盟属于一个锦标赛 当我加载冠军实体时,关联的联盟会附带已经加载的竞争对

我遇到了一个关于Hibernate延迟加载的问题。我在Hibernate论坛上发布了这篇文章,但没有收到任何回复,所以我想也许stackoverflow上的各位可以帮我一把。帖子链接是: 我正在复制以下内容,提前感谢:

问题是我试图延迟加载一个集合,但它总是被急切地加载,这对我的应用程序性能产生了巨大的影响。这里是场景,我描述了涉及的3个类的模型:

冠军:有一个联赛冠军有一个默认联赛

联盟:有许多竞争对手-属于一个锦标赛许多联盟属于一个锦标赛

当我加载冠军实体时,关联的联盟会附带已经加载的竞争对手列表,即使我的映射文件中有lazy=true。我正在粘贴这3个实体的映射文件的相关部分:

***************************************************************************************
<class name="Championship" table="Championships">

<id name="id" type="long" column="id">
  <generator class="native" />
</id>
<many-to-one name="defaultLeague" lazy="false" cascade="all" class="League" not-null="true"  column="Default_League_FK"  unique="true" not-found="ignore"/>

</class>

****************************************************************************************
<class name="League" table="League">

<id name="id" type="long" column="id">
  <generator class="native" />
</id>

<many-to-one name="championship" lazy="false"
class="Championship" column="Championship_FK" />

<list name="competitorsList" table="Competitors_League" cascade="all" lazy="true">
    <key column="League_FK" not-null="true"/>
<index column="LeagueIndex" type="long"/>
<one-to-many class="Competitor" />
</list>

</class>
*****************************************************************************************
<class name="Competitor" table="Competitors_League" >

<key column="id"/>

<many-to-one name="league" lazy="false" class="League" not-null="true" insert="false" update="false" column="League_FK" />

</class>
******************************************************************************************
当我加载冠军实例时,冠军->联盟->竞争对手列表已经加载了所有列表元素。这不应该发生,因为我在我的联盟映射上有lazy=true:

<list name=" competitorsList" table="Competitors_League" cascade="all" lazy="true">
我已经尝试了许多不同的方法,我可以让它工作,即使看起来我的映射设置正确

你们能帮帮我吗?任何帮助都会非常感激,因为我被困在这里了

如果你需要任何额外的信息,请告诉我。 谢谢

注释

注意1:集合是在视图层中访问的,在视图中没有打开的会话过滤器之类的东西。我应该收到LazyInitializationException,这是预期的行为,而不是急切地加载集合

注2:我添加类模型是为了提供一些额外的语义上下文:

public class League{

   private Championship championship;
       private List<Competitor> competitorsList;

}

*********************************

public class Championship {

   private League defaultLeague;
}
**********************************

public class Competitor{

   private League league;
}
注意3:Hibernate.isInitializedleague.competitorList返回TRUE。获取属性已删除,但行为相同

注4:日志记录不显示已获取集合。我已经设置了调试级别无法使信息级别抛出结果,这里是控制台输出

19:14:35,953 DEBUG ErrorCounter:68 - throwQueryException() : no errors
19:14:35,959 DEBUG HqlSqlBaseWalker:111 - select << begin [level=1, statement=select]
19:14:35,966 DEBUG FromElement:108 - FromClause{level=1} :  com.sportsdt.model.championship (no alias) -> championship0_
19:14:35,972 DEBUG FromReferenceNode:51 - Resolved :  {synthetic-alias} -> {synthetic-alias}
19:14:35,979 DEBUG DotNode:569 - getDataType() : enJuego -> org.hibernate.type.BooleanType@1d50d84
19:14:35,985 DEBUG FromReferenceNode:51 - Resolved :  {synthetic-alias}.enJuego -> championship0_.en_juego
19:14:35,991 DEBUG FromReferenceNode:51 - Resolved :  {synthetic-alias} -> {synthetic-alias}
19:14:35,998 DEBUG DotNode:569 - getDataType() : competencia -> org.hibernate.type.ManyToOneType(com.sportsdt.model.Competencia)
19:14:36,004 DEBUG DotNode:526 - dereferenceShortcut() : property competencia in com.sportsdt.model.championship does not require a join.
19:14:36,011 DEBUG DotNode:555 - terminal propertyPath = [competencia]
19:14:36,017 DEBUG FromReferenceNode:51 - Resolved :  {synthetic-alias}.competencia -> championship0_.idCompetencia
19:14:36,023 DEBUG HqlSqlBaseWalker:117 - select : finishing up [level=1, statement=select]
19:14:36,030 DEBUG HqlSqlWalker:509 - processQuery() :  ( SELECT ( FromClause{level=1} championships championship0_ ) ( where ( and ( = ( championship0_.en_juego {synthetic-alias} enJuego ) ? ) ( = ( championship0_.idCompetencia {synthetic-alias} competencia ) ? ) ) ) )
19:14:36,036 DEBUG HqlSqlWalker:716 - Derived SELECT clause created.
19:14:36,042 DEBUG JoinProcessor:148 - Using FROM fragment [championships championship0_]
19:14:36,053 DEBUG HqlSqlBaseWalker:123 - select >> end [level=1, statement=select]
19:14:36,067 DEBUG AST:232 - --- SQL AST ---
-[SELECT] QueryNode: 'SELECT'  querySpaces (championships)
+-[SELECT_CLAUSE] SelectClause: '{derived select clause}'
|  +-[SELECT_EXPR] SelectExpressionImpl: 'championship0_.id as id29_' {FromElement{explicit,not a collection join,not a fetch join,fetch non-lazy properties,classAlias=null,role=null,tableName=championships,tableAlias=championship0_,origin=null,colums={,className=com.sportsdt.model.championship}}}
|  \-[SQL_TOKEN] SqlFragment: 'championship0_.nombre as nombre29_, championship0_.cantidadFechas as cantidad3_29_, championship0_.fecha_inicio as fecha4_29_, championship0_.fecha_fin as fecha5_29_, championship0_.en_juego as en6_29_, championship0_.idCompetencia as idCompet7_29_, championship0_.disponible_penca as disponible8_29_, championship0_.disponible_entrenador as disponible9_29_, championship0_.League_General_FK as League10_29_'
+-[FROM] FromClause: 'from' FromClause{level=1, fromElementCounter=1, fromElements=1, fromElementByClassAlias=[], fromElementByTableAlias=[championship0_], fromElementsByPath=[], collectionJoinFromElementsByPath=[], impliedElements=[]}
|  \-[FROM_FRAGMENT] FromElement: 'championships championship0_' FromElement{explicit,not a collection join,not a fetch join,fetch non-lazy properties,classAlias=null,role=null,tableName=championships,tableAlias=championship0_,origin=null,colums={,className=com.sportsdt.model.championship}}
\-[WHERE] SqlNode: 'where'
   \-[AND] SqlNode: 'and'
      +-[EQ] BinaryLogicOperatorNode: '='
      |  +-[DOT] DotNode: 'championship0_.en_juego' {propertyName=enJuego,dereferenceType=4,propertyPath=enJuego,path={synthetic-alias}.enJuego,tableAlias=championship0_,className=com.sportsdt.model.championship,classAlias=null}
      |  |  +-[IDENT] IdentNode: '{synthetic-alias}' {originalText={synthetic-alias}}
      |  |  \-[IDENT] IdentNode: 'enJuego' {originalText=enJuego}
      |  \-[PARAM] ParameterNode: '?' {ordinal=0, expectedType=org.hibernate.type.BooleanType@1d50d84}
      \-[EQ] BinaryLogicOperatorNode: '='
         +-[DOT] DotNode: 'championship0_.idCompetencia' {propertyName=competencia,dereferenceType=ROOT_LEVEL,propertyPath=competencia,path={synthetic-alias}.competencia,tableAlias=championship0_,className=com.sportsdt.model.championship,classAlias=null}
         |  +-[IDENT] IdentNode: '{synthetic-alias}' {originalText={synthetic-alias}}
         |  \-[IDENT] IdentNode: 'competencia' {originalText=competencia}
         \-[PARAM] ParameterNode: '?' {ordinal=1, expectedType=org.hibernate.type.ManyToOneType(com.sportsdt.model.Competencia)}

19:14:36,074 DEBUG ErrorCounter:68 - throwQueryException() : no errors
19:14:36,080 DEBUG QueryTranslatorImpl:216 - HQL: from com.sportsdt.model.championship where enJuego=? and competencia=?
19:14:36,086 DEBUG QueryTranslatorImpl:217 - SQL: select championship0_.id as id29_, championship0_.nombre as nombre29_, championship0_.cantidadFechas as cantidad3_29_, championship0_.fecha_inicio as fecha4_29_, championship0_.fecha_fin as fecha5_29_, championship0_.en_juego as en6_29_, championship0_.idCompetencia as idCompet7_29_, championship0_.disponible_penca as disponible8_29_, championship0_.disponible_entrenador as disponible9_29_, championship0_.League_General_FK as League10_29_ from championships championship0_ where championship0_.en_juego=? and championship0_.idCompetencia=?
19:14:36,092 DEBUG ErrorCounter:68 - throwQueryException() : no errors
19:14:54,360 DEBUG JDBCTransaction:103 - commit
19:14:57,136 DEBUG JDBCTransaction:193 - re-enabling autocommit
19:14:57,141 DEBUG JDBCTransaction:116 - committed JDBC Connection

如果我设置log4j.logger.org.hibernate.SQL=debug,它会像预期的那样显示大量的select,这些操作包括针对表的select和JOIN,但就我所见,这些混乱的信息是无用的。

从未使用过基于xml的实体描述,但下面的链接可能对您有用

定义从数据库获取数据的策略。渴望的 策略是持久性提供程序运行时的一项要求 必须急切地获取数据。懒惰策略是对 持久性提供程序运行时,在 首先访问它。允许实现急切地获取 已为其指定惰性策略提示的数据


另一个问题是,您如何确定竞争对手是否热切期待。例如,对getCompetitorsList.size的任何调用都将导致加载列表。如果不是这样,您应该寻找特定于hibernate的配置选项,以保证延迟加载。

您使用的是一对一关联。不要。你的使用意味着联盟和冠军拥有相同的主键

设置了多对一的正确倒数

从你的描述中我看不出这个数字。但如果一个联赛只有一个冠军,那么在联赛中你应该:

    <set name="allChampions" access="field"
        cascade="all-delete-orphan" lazy="true">
        <key column="league" not-null="true"/>
        <one-to-many class="Championship"/>
    </set>
同样地,你的竞争对手名单应该是一套,除非你有理由订购竞争对手

顺便问一下,类名开头的所有空格是什么意思

更新:

你怎么知道这个列表正在被急切地获取?我建议打开sql日志,以确保调试不会导致问题。 删除获取属性。fetch影响加载,并对加载有副作用。 使用org.hibernate.hibernate.isInitializedleague.competitorList查看列表是否真正初始化

此log4j.xml代码段将有助于记录以确定何时提取集合:

   <logger name="org.hibernate">
      <level value="INFO"/>
   </logger>
    <!-- log HQL query parser activity -->
   <logger name="org.hibernate.hql.ast.AST">
      <level value="INFO"/>
   </logger>
    <!-- log just the SQL -->
   <logger name="org.hibernate.SQL">
      <level value="INFO"/>
   </logger>
    <!-- log JDBC bind parameters     -->
   <logger name="org.hibernate.type">
      <level value="INFO"/>
   </logger>

    <!-- log schema export/update -->
   <logger name="org.hibernate.tool.hbm2ddl">
      <level value="INFO"/>
   </logger>

    <!-- log HQL parse trees -->
   <logger name="org.hibernate.hql">
      <level value="INFO"/>
   </logger>
    <!-- log cache activity -->
   <logger name="org.hibernate.cache">
      <level value="INFO"/>
   </logger>
    <!-- log transaction activity (TRACE for very detailed) -->
   <logger name="org.hibernate.transaction">
      <level value="INFO"/>
   </logger>
   <!-- log JDBC resource acquisition -->
   <logger name="org.hibernate.jdbc">
      <level value="INFO"/>
   </logger>

我添加了类模型,以便在这里引入一些语义。实际上,我使用的是多对一,unique=true,如下所述:。联赛冠军协会不是双向的,一个冠军有一个默认的联赛多对一,不同的联赛不同,作为一个单独的事情,联赛属于一个冠军,一对一是一个错误,我编辑了,感谢响应,我使用的是纯Hibernate,而不是JPA,设置了懒惰策略。关于第二个问题,我已经更新了包含该信息的帖子。