上下文:使用播放框架(1.3),休眠(4.3.8)和html端的某些Groovy开发内部Web应用程序。
我目前正在与Hibernate合作,我被分配去寻找一些优化技术。我们遇到了一些加载问题,因为所有内容都是懒惰地获取的,当我们尝试使用Groovy访问它时,Hibernate将减少大量请求,这将花费大量时间,使我们的应用程序真的很慢。
所以我试图调整我们的find方法来获取我需要的所有东西,这样Hibernate不必这样做。
这是我的班级:
@实体 @Table(name =“ business_partner”,schema =“ public”) 公共类BusinessPartner扩展了模型{ @ID @Column(name =“ business_partner_id”,updatable = false,nullable = false) @GeneratedValue(strategy = GenerationType.TABLE,generator =“ businessPartnerGenerator”) @TableGenerator(name =“ businessPartnerGenerator”, table =“ key_generator”, pkColumnName =“ table_name”, valueColumnName =“ next_id”, distributionSize = 1) 私有Integer businessPartnerId; @ManyToOne(获取= FetchType.LAZY) @JoinColumn(name =“ airline_id”) @独特 私人航空公司; @ManyToOne(获取= FetchType.LAZY) @JoinColumn(name =“ trader_country_id”) 私人国家商人国家; @Column(name =“ name”,可为空= false) @需要 @MaxSize(50) @独特 私有字符串名称; @Column(名称=“代码”,可更新=假) @MaxSize(5) @独特 私有字符串代码; @Column(name =“ is_active”,nullable = false) private Boolean isActive; @OneToMany(获取= FetchType.LAZY,mappedBy =“ businessPartner”,cascade = CascadeType.ALL) @Fetch(FetchMode.SUBSELECT) 私有列表lstBusinessPartnerTypes = new ArrayList(); @OneToMany(获取= FetchType.LAZY,mappedBy =“ businessPartner”,cascade = CascadeType.ALL) @Fetch(FetchMode.SUBSELECT) 私有列表lstBusinessPartnerAddresses = new ArrayList();
这是我的标准:
公共静态列表findAll(){ 会话oSession = SessionManager.createSession(); 列表lstBusinessPartners =(List)oSession.createCriteria(BusinessPartner.class) .createAlias(“ lstBusinessPartnerAddresses,” lstBPA“) .createAlias(“ lstBusinessPartnerTypes”,“ lstBPT”) .setFetchMode(“ airline”,FetchMode.JOIN) .setFetchMode(“ lstBPA.country”,FetchMode.SELECT) .setFetchMode(“ lstBPT.typeBusinessPartner”,FetchMode.SELECT) .addOrder(Order.asc(“ code”)) .list(); SessionManager.closeSession(oSession); 返回lstBusinessPartners; }
所以我需要访问航空公司和每个列表中的一个孩子。
我可以使用航空公司,那里没有问题。当我尝试访问列表中的对象时,它变得很棘手。我既无法加载列表,也无法加载其子级(从我的标准中可以看出,我试图在一个列表中访问国家/地区,在另一个列表中键入业务伙伴)。我收到每个业务伙伴的这种要求:
所以我的问题是:是否可以使用条件获取懒惰列表?如果可以,怎么办?
[因此,如果有人偶然发现这篇文章以寻找答案,我就找到了答案。您需要为列表创建别名并指定JoinType,如下所示:
BusinessPartner oBusinessPartner = (BusinessPartner)oSession.createCriteria(BusinessPartner.class, "BP")
.add(Restrictions.eq("businessPartnerId", iBusinessPartnerId))
.createAlias("lstBusinessPartnerTypes", "lstBPT", JoinType.LEFT_OUTER_JOIN)
.createAlias("lstBPT.typeBusinessPartner", "TBP", JoinType.LEFT_OUTER_JOIN)
.createAlias("lstBPT.accountGroup", "AG", JoinType.LEFT_OUTER_JOIN)
.createAlias("AG.typeBusinessPartner", "AGTBP", JoinType.LEFT_OUTER_JOIN)
.createAlias("lstBusinessPartnerAddresses", "lstBPA", JoinType.LEFT_OUTER_JOIN)
.createAlias("lstBPA.country", "BPAC", JoinType.LEFT_OUTER_JOIN)
.createAlias("lstBPA.language", "BPAL", JoinType.LEFT_OUTER_JOIN)
.uniqueResult();
您可以使用Hibernate.initialize(Object)方法初始化每个集合。因此,在您的DAO层中,仅需要检索“父亲”对象,然后为每个孩子调用此方法。