如何强制在HQL中加载eager

时间:2013-07-29 16:43:07

标签: hibernate annotations hql eager-loading

我正在尝试强制HQL急切加载所有Lazy属性。 使用FETCH给了我“多包”例外,我无法将其更改为Set,因为它们在其他地方被引用。我尝试了其他映射注释但没有运气。 忽略“FETCH ALL PROPERTIES”并且不加载任何内容。我从来不明白它到底是做什么的。显然,当JSF尝试读取List时,我得到“无法初始化惰性列表。连接已关闭”

我正在使用Hibernate 4.0。 所以这是我的HQL查询:

Select r from Responsavel r FETCH ALL PROPERTIES 
where r.unidadeEmpresarial.id = :idUnidade

这是我的模特课:

public class Responsavel {

@Id
@SequenceGenerator(name = "SQ_RESPONSAVEL_GENERATOR", sequenceName = "SE_RESPONSAVEL", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SQ_RESPONSAVEL_GENERATOR")
@Column(name = "SQ_RESPONSAVEL")
private Long id;

@Temporal(TemporalType.DATE)
@Column(name = "DT_FIM")
private Date dataFim;

@NotNull
@Temporal(TemporalType.DATE)
@Column(name = "DT_INICIO")
private Date dataInicio;

@Temporal(TemporalType.DATE)
@Column(name = "DT_NASCIMENTO")
private Date dataNascimento;

@Type(type = "org.hibernate.type.NumericBooleanType")
@Column(name = "IN_PODER_ADM_REPRES")
private Boolean temPoderAdministrativo;

@Column(name = "NO_RESPONSAVEL")
private String nome;

@Column(name = "NU_CPF_CNPJ_RESPONSAVEL")
private String numeroCpfCnpj;

@NotNull
@Enumerated(EnumType.STRING)
@Column(name = "TP_PESSOA")
private String tipoPessoa;

@ManyToOne
@JoinColumn(name = "SQ_PAIS")
private Pais pais;

@Column(name = "VL_CAPITAL_SOCIAL")
private BigDecimal valorCapitalSocial;

@Column(name = "PC_CAPITAL_SOCIAL")
private BigDecimal percentualCapitalSocial;

@ManyToOne
@JoinColumn(name = "SQ_UNIDADE_EMPRESARIAL")
private UnidadeEmpresarial unidadeEmpresarial;

@OneToMany(mappedBy = "responsavel", fetch = FetchType.LAZY)
@Fetch(FetchMode.SUBSELECT)
private Set<ResponsavelQualificacaoResponsavel> listaResponsavelQualificacaoResponsavel;

@OneToMany(mappedBy = "responsavel")
private List<Representante> representantes;

@OneToMany(mappedBy = "responsavel")
private List<ContatoResponsavel> contatoResponsavel;

@OneToMany(mappedBy = "responsavel", cascade = CascadeType.ALL)
private List<EnderecoResponsavel> enderecoResponsavel;

}

由于

1 个答案:

答案 0 :(得分:1)

如果您获得多个包的例外,那么这是因为Hibernate无法立即获取所有收藏品。您应该选择要使用基本查询选择的集合,并使用连接进行选择,然后使用Hibernate.initialize获取所需的其余集合。

所以它看起来像这样(我离开了选择,因为它不是必需的):

from Responsavel r 
join fetch pais p
join fetch unidadeEmpresarial u
join fetch representantes s
where r.unidadeEmpresarial.id = :idUnidade

您可以尝试包含哪些内容。剩下的就是,如果你希望从Hibernate会话中分离出来,需要初始化,例如,使用前端或服务类中的集合。

Hibernate.initialize(listaResponsavelQualificacaoResponsavel);
Hibernate.initialize(contatoResponsavel);
Hibernate.initialize(enderecoResponsavel);

如果您将保留会话,则无需初始化,它们将按需初始化(尽管这可能会导致性能问题,具体取决于您的用例)。