Hibernate覆盖“lazy = false”

时间:2014-08-06 15:10:04

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

我正在研究现有项目中的新模块。该项目已经有一个用户表,一个pojo和一个相应的映射文件。问题是他们通过提及 lazy =“false”来热切地获取所有属性。但是,在我的模块中,我正在做大量的阅读和阅读。写入一个请求,所以我不想急切地获取。我想知道的是,是否可以为同一个表创建另一个映射文件&同样的pojo懒洋洋地加载所有属性?我尝试为映射文件分配不同的实体名称,但在部署时,我收到错误“实体映射中的重复列”

我看到了this回答,但它说“不要映射孩子”,那么我将如何获得代理?

5 个答案:

答案 0 :(得分:3)

使用EAGER抓取作为默认策略的一个主要缺点。通常你会有一个LAZY儿童系列,你可以eagerly fetch on a HQL query basis

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

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

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

答案 1 :(得分:2)

我认为,你的问题是不要加载相关实体,勉强? 为此: FetchType.LAZY =除非通过getter显式调用,否则不加载关系。 FetchType.EAGER =加载所有关系默认

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

像Vlad Mihalcea所说,使用Criteria API它会起作用。我试过了:)

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

至少你可以不用改变现有的hbm文件

答案 4 :(得分:0)

一些其他方法提到我们使用基于JPA继承(@MappedSuperclass)和/或数据库视图,并使用以下伪代码进行了示例(它同时适用于 EAGER-> LAZY LAZY-> 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 ; }
    

因此您可以将[{1}}或DaoXLazy用于所需的方案。

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

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

prop_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  )