获取惰性一对多列表的 children
Fetch the children of a lazy one to many list
上下文:使用 play 框架 (1.3)、hibernate (4.3.8) 和 html 方面的一些 Groovy 开发 in-house 网络应用程序。
我目前正在使用 Hibernate,我被指派去寻找一些优化技术。我们遇到了一些加载问题,因为所有内容都是延迟获取的,当我们尝试使用 Groovy 访问它时,Hibernate 会大量请求,这会花费大量时间,使我们的应用程序变得非常慢。
所以我正在尝试调整我们的查找方法以获取我需要的所有内容,这样 Hibernate 就不必这样做了。
这是我的 class :
@Entity
@Table(name="business_partner", schema = "public")
public class BusinessPartner extends Model{
@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",
allocationSize=1)
private Integer businessPartnerId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "airline_id")
@Unique
private Airline airline;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "trader_country_id")
private Country traderCountry;
@Column(name = "name", nullable = false)
@Required
@MaxSize(50)
@Unique
private String name;
@Column(name = "code", updatable = false)
@MaxSize(5)
@Unique
private String code;
@Column(name = "is_active", nullable = false)
private Boolean isActive;
@OneToMany(fetch = FetchType.LAZY, mappedBy="businessPartner", cascade=CascadeType.ALL)
@Fetch(FetchMode.SUBSELECT)
private List lstBusinessPartnerTypes = new ArrayList();
@OneToMany(fetch = FetchType.LAZY, mappedBy="businessPartner", cascade=CascadeType.ALL)
@Fetch(FetchMode.SUBSELECT)
private List lstBusinessPartnerAddresses = new ArrayList();
这是我的标准:
public static List findAll(){
Session oSession = SessionManager.createSession();
List 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);
return lstBusinessPartners;
}
所以我需要访问航空公司和每个一对多列表的 child。
我可以访问航空公司,那里没有问题。当我尝试访问列表中的 object 时,它变得很棘手。我无法加载列表及其 child(正如您从我的标准中看到的那样,我试图在一个列表中访问国家/地区并在另一个列表中键入业务合作伙伴)。我对每个商业伙伴都有这样的要求:
Hibernate example
所以我的问题是:是否可以使用条件获取惰性列表?如果是的话怎么办?
因此,如果有人在寻找答案时无意中发现了这个 post,我找到了我的答案。您需要为您的列表创建别名并指定 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 层中,只需要检索 'father' 对象,然后为每个子对象调用此方法。
上下文:使用 play 框架 (1.3)、hibernate (4.3.8) 和 html 方面的一些 Groovy 开发 in-house 网络应用程序。
我目前正在使用 Hibernate,我被指派去寻找一些优化技术。我们遇到了一些加载问题,因为所有内容都是延迟获取的,当我们尝试使用 Groovy 访问它时,Hibernate 会大量请求,这会花费大量时间,使我们的应用程序变得非常慢。
所以我正在尝试调整我们的查找方法以获取我需要的所有内容,这样 Hibernate 就不必这样做了。
这是我的 class :
@Entity @Table(name="business_partner", schema = "public") public class BusinessPartner extends Model{ @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", allocationSize=1) private Integer businessPartnerId; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "airline_id") @Unique private Airline airline; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "trader_country_id") private Country traderCountry; @Column(name = "name", nullable = false) @Required @MaxSize(50) @Unique private String name; @Column(name = "code", updatable = false) @MaxSize(5) @Unique private String code; @Column(name = "is_active", nullable = false) private Boolean isActive; @OneToMany(fetch = FetchType.LAZY, mappedBy="businessPartner", cascade=CascadeType.ALL) @Fetch(FetchMode.SUBSELECT) private List lstBusinessPartnerTypes = new ArrayList(); @OneToMany(fetch = FetchType.LAZY, mappedBy="businessPartner", cascade=CascadeType.ALL) @Fetch(FetchMode.SUBSELECT) private List lstBusinessPartnerAddresses = new ArrayList();
这是我的标准:
public static List findAll(){ Session oSession = SessionManager.createSession(); List 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); return lstBusinessPartners; }
所以我需要访问航空公司和每个一对多列表的 child。
我可以访问航空公司,那里没有问题。当我尝试访问列表中的 object 时,它变得很棘手。我无法加载列表及其 child(正如您从我的标准中看到的那样,我试图在一个列表中访问国家/地区并在另一个列表中键入业务合作伙伴)。我对每个商业伙伴都有这样的要求:
Hibernate example
所以我的问题是:是否可以使用条件获取惰性列表?如果是的话怎么办?
因此,如果有人在寻找答案时无意中发现了这个 post,我找到了我的答案。您需要为您的列表创建别名并指定 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 层中,只需要检索 'father' 对象,然后为每个子对象调用此方法。