【问题标题】:Hibernate override "lazy=false"休眠覆盖“懒惰=假”
【发布时间】:2014-08-06 15:10:03
【问题描述】:

我正在现有项目中开发一个新模块。该项目已经有一个用户表、一个 pojo 和一个相应的映射文件。问题是他们通过提及 lazy="false" 急切地获取所有属性。但是,在我的模块中,我在一个请求中进行了大量的读写操作,所以我不想急切地获取。我想知道的是,是否可以为同一个表和同一个 pojo 创建另一个映射文件来懒惰地加载所有属性?我尝试为映射文件分配不同的 entity-name,但在部署时,我收到错误 “Repeated column in mapping for entity”

我看到this 的回答,但上面写着“不要映射孩子”,那么我将如何获得代理?

【问题讨论】:

    标签: java hibernate jpa lazy-loading hibernate-mapping


    【解决方案1】:

    这是使用 EAGER 获取作为默认策略的一个主要缺点。通常你会有一个懒惰的儿童收藏,你可以eagerly fetch on a HQL query basis

    值得一提的是HQL/Criteria queries overrule the default fetch strategy(由您的实体映射给出),以便您可以明确指定要获取的内容。

    对于条件查询,您可以尝试Criteria.setFetchModeFetchMode.LAZY,尽管它已被弃用。

    另一种否决 EAGER 提取的方法是使用 javax.persistence.fetchgraph。这样,您可以指定要获取的内容,并且将延迟获取未包含在实体图中的所有 EAGER 获取属性。

    【讨论】:

      【解决方案2】:

      我认为,您的问题是不加载关联实体,例如? 为此,当: FetchType.LAZY = 除非通过 getter 显式调用,否则不加载关系。 FetchType.EAGER = 默认加载所有关系

      在你的情况下,如果我的理解是正确的,那么使用 懒惰=“假” fetch="select" 因此它将通过 getter 按需选择。 检查这个网址,它会给出更清晰的想法: Hibernate XML Mapping: Lazy False or Fetch Select? A Short Primer On Fetching Strategies

      【讨论】:

        【解决方案3】:

        Hibernate mapping setting lazy = 'false' 的意思是,如果你使用两个不同的 java 类,你可以映射同一个表两次。在您的情况下,如果您知道设置 lazy="true" 就足够了:

        1. 创建你的 pojo 的空子类
        2. 以您希望的方式将您的子类映射到同一个用户表(例如复制粘贴现有映射和更改惰性属性值)
        3. 在您创建的模块中只使用子类

        【讨论】:

          【解决方案4】:

          就像 Vlad Mihalcea 所说,使用 Criteria API 就可以了。我试过了:)

          Criteria c =  session.createCriteria(YourHibernateClass.class);
          c.setFetchMode(urLazyPropName,FetchMode.LAZY);
          

          至少您可以在不更改现有 hbm 文件的情况下做到这一点

          【讨论】:

            【解决方案5】:

            一些其他方法提到我们使用基于 JPA 继承 (@MappedSuperclass) 和/或数据库视图,并用以下伪代码举例说明(它适用于两种方式EAGER->LAZYLAZY->EAGER 场景):

            @Table( name = "table_x" )
            @Entity
            class DaoX { @...( fetch = FetchType.EAGER ) refY ;  /* ... other stuff ... */ }
            
            • 我们的DaoX 使用例如在像这样的其他代码中:

              DaoX x ;
              
              @Entity
              class DaoZ {  DaoX x ; }
              

            通过继承

            所以如果我们想让它延迟加载,我们可以像这样只用最少的额外代码来提升继承层次结构:

            @Table( name = "table_x" )
            @MappedSuperclass
            class abstract BaseDaoX { /* ... other stuff ... */ }
            
            @Entity
            class DaoX extends BaseDaoX { @...( fetch = FetchType.EAGER ) refY ; }
            
            @Entity
            class DaoXLazy extends BaseDaoX { @...( fetch = FetchType.LAZY ) refY ; }
            
            • 我们的 DaoX 用法应尽可能替换为 BaseDaoX(无直接 JPA 映射)

              BaseDaoX x ;
              
              @Entity
              class DaoZ {  DaoX x ; }
              
              @Entity
              class DaoZLazy {  DaoXLazy x ; }
              

            因此您可以将DaoXLazyDaoZLazy 用于您想要的场景。

            通过视图(在 LAZY->EAGER 场景中)

            (如果您可以将当前的EAGER 更改为LAZY,这通常更合适) 你可以用最小的负载映射你的(可能是深度嵌套的)懒惰的东西,例如像这样(我们喜欢在这里加载prop_f1prop_b1

            -- db view:
            create or replace view view_x_eager as
            select 
              tx.*,
              f.prop_f1,
              b.prop_b1
            from table_x                 tx
              -- assuming tx:f ~ 1:1 and f:b ~ 1:1 for simplicity here:
              left outer join table_foo  f  on ( f.id = tx.foo_id )
              left outer join table_bar  b  on ( b.id = f.bar_id  )
            

            @Table( name = "view_x_eager" )
            class DaoXEager extends BaseDaoX { 
              @...( fetch = FetchType.EAGER ) refY ; 
            
              String prop_f1 ;
              String prop_b1 ;
            }
            

            【讨论】:

            • 您好,我正在使用您的 MappedSuperClass 继承策略。但是,我在“字段列表”中得到“未知列”structs0_.project_lazy_id,其中休眠正在更改外键。我不知道如何保持默认状态。试过@JoinColumn 等。在这里查看我的代码:gist.github.com/nitrag/7d685355765aa88853862f560d21f0d8
            • 嗨@Ryan,请在一些休眠论坛或关于stackoverflow的新问题中提问,因为我现在无法帮助您。您可以在此处通过评论将其他人指出您的问题。
            猜你喜欢
            • 1970-01-01
            • 2019-02-02
            • 2010-11-11
            • 1970-01-01
            • 2011-03-14
            • 2014-07-31
            • 2012-06-15
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多