从懒惰的一个到多个列表

时间:2016-10-18 09:08:39

标签: hibernate groovy alias fetch hibernate-criteria

上下文:使用play框架(1.3),hibernate(4.3.8)和html端的一些Groovy开发内部Web应用程序。

我目前正在使用Hibernate,我被分配了一些优化技术。我们有一些加载问题,因为一切都是懒散的,当我们尝试使用Groovy访问它时,Hibernate将减少大量的请求,这需要花费大量时间使我们的应用程序真的很慢。

所以我试图调整我们的find方法来获取我需要的所有内容,以便Hibernate不必这样做。

这是我的班级:


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

所以我需要访问航空公司和每个人到多个名单的孩子。

我可以访问航空公司,那里没有问题。当我尝试访问列表中的对象时,它变得棘手。我无法加载列表或他们的孩子(正如您从我的标准中可以看到我试图在一个列表中访问国家/地区并在另一个列表中键入业务伙伴)。我得到了每个商业伙伴的这种要求:

Hibernate example

所以我的问题是:是否可以使用条件获取惰性列表?如果是这样的话?

2 个答案:

答案 0 :(得分:1)

所以我找到了答案,如果有人在这篇文章中发现了寻找答案。您需要为列表创建别名,并指定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();

答案 1 :(得分:1)

您可以使用Hibernate.initialize(Object)方法初始化每个集合。因此,在您的DAO层中,只需要检索“父亲”即可。对象,然后为每个孩子调用此方法。