Context : Development of in-house web applications using play framework (1.3), hibernate (4.3.8) and some Groovy on the html side.
I'm currently working with Hibernate and I was assigned to find some optimization techniques. We have some loading issue because everything is fetched lazily and when we try to access it with Groovy, Hibernate will rain down tons of requests that takes a huge amount of time making our applications really slow.
So I'm trying to tweak our find method to fetch everything that I need so that Hibernate don't have to.
Here's my 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();
Here's my criteria :
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; }
So I need to access airline and a child of each one to many lists.
I can access airline, there is no problem there. It's when I try to access an object in the list that it gets tricky. I can't load the lists nor their child (as you can see from my criteria I'm trying to access country in one list and type business partner in the other). I get this kind of request for every business partner :
So my question is this : Is it possible to fetch a lazy list using criteria ? And if so how ?