Hibernate覆盖“lazy = false”

问题描述 投票:9回答:5

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

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

java hibernate jpa lazy-loading hibernate-mapping
5个回答
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获取属性。


2
投票

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

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


1
投票

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

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

0
投票

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

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

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


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 ; }

via inheritance

因此,如果我们想延迟加载它,我们可以像这样使用最少的附加代码来对继承层次进行操作:

@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来实现你想要的场景。

via views (in LAZY->EAGER scenarios)

(如果您可以将当前的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 ;
}
© www.soinside.com 2019 - 2024. All rights reserved.