Zdravím,
Batch loading jsem zkoušel, ale získal jsem mnohem horší výsledky než u
obyčejného lazy. Testoval jsem na databázi derby.
Volal jsem Invoice.all dotaz, v db jsem měl 10000 záznamů Invoice, každý se 4mi
InvoiceEntry. S @Fetch(SELECT) a @Fetch(JOIN) trval 30s.
S @BatchSize(size = 3) to trvalo 330s
for(Invoice i: invoiceDao.getAll()){
for (InvoiceEntry e: i.getInvoiceEntries()){
System.out.println(e.getName()+ " " + count);
}
count++;
}
Jen mě překvapilo, že se neupoužívá ten join v sql při @Fetch(JOIN). Zkusím
ještě tu jinou verzi hibernate, používám 3.2.4.sp1.
Martin
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Petr Ferschmann
Sent: Thursday, June 07, 2007 11:10 AM
To: Java
Subject: Re: Hibernate @Fetch(JOIN)
Zdravím,
nebo využít vlastnost zvanou Batch Loading. Dotazy pak vypadají takto:
Hibernate: select invoice0_.id as id0_, invoice0_.created as created0_ from
Invoice invoice0_
Hibernate: select invoiceent0_.INVOICE_FK as INVOICE3_1_, invoiceent0_.id as
id1_,
invoiceent0_.id as id1_0_, invoiceent0_.INVOICE_FK as INVOICE3_1_0_,
invoiceent0_.name as name1_0_
from InvoiceEntry invoiceent0_ where invoiceent0_.INVOICE_FK in (?, ?, ?)
Je to výborný kompromis mezi lazy a eager loadingem se zachováním výkonu -
nemusím mít pak dotazy typu "vrať mi zakázky a k nim jejich položky" a "vrať mi
zakázky"
přičemž obě vrací "jen" kolekci zakázek.
Jiri Mares píše v Čt 07. 06. 2007 v 09:39 +0200:
Ahoj, asi by nebylo nezajimave zminit verzi Hibernate ...
Pokud pouzivate dotaz, pak jste schopen zapisem inner join fetch nebo outer
join fetch donutit hibernate aby to dotahla
rovnou. Chovani Hibernate je spis to nedelat a zavisle entity tahat separatnimi
dotazy, aby se dalo vyuzivat cachovani.
Takze pro vas pripad asi neco:
from Invoice as i inner join fetch i.invoiceEntries
Jirka
Martin Chalupa napsal(a):
> Dobrý den, ladím rychlost hibernatu při načítání provázaných entit a
> narazil jsem na následující věc. Mám tyto entity.
>
>
>
> @Entity
>
> @NamedQueries({
>
> @NamedQuery(name = "Invoice.all", query = "from Invoice"),
>
> @NamedQuery(name = "Invoice.allFetch", query = "select distinct i
> from Invoice as i left join fetch i.invoiceEntries")
>
> })
>
> public class Invoice {
>
> @Id
>
> @GeneratedValue(strategy = GenerationType.AUTO)
>
> private Long id;
>
> @Basic
>
> private Date created;
>
> @OneToMany(cascade = CascadeType.ALL, mappedBy = "invoice)
>
> @Fetch(FetchMode.JOIN)
>
> private Set<InvoiceEntry> invoiceEntries;
>
> }
>
>
>
> @Entity
>
> public class InvoiceEntry {
>
> @Id
>
> @GeneratedValue(strategy = GenerationType.AUTO)
>
> private Long id;
>
> @Basic
>
> private String name;
>
> @ManyToOne
>
> @JoinColumn(name="INVOICE_FK")
>
> private Invoice invoice;
>
> }
>
>
>
> Volám tento dotaz:
> sessionFactory.getCurrentSession().getNamedQuery("Invoice.all").list();
>
>
>
> V této konfiguraci bych očekával v logu jeden provedený dotaz který bude
> obsahovat join, ale je tam toto:
>
>
>
> Hibernate: select invoice0_.id as id0_, invoice0_.created as created0_
> from Invoice invoice0_
>
> Hibernate: select invoiceent0_.INVOICE_FK as INVOICE3_1_,
> invoiceent0_.id as id1_, invoiceent0_.id as id1_0_,
> invoiceent0_.INVOICE_FK as INVOICE3_1_0_, invoiceent0_.name as name1_0_
> from InvoiceEntry invoiceent0_ where invoiceent0_.INVOICE_FK=?
>
> Hibernate: select invoiceent0_.INVOICE_FK as INVOICE3_1_,
> invoiceent0_.id as id1_, invoiceent0_.id as id1_0_,
> invoiceent0_.INVOICE_FK as INVOICE3_1_0_, invoiceent0_.name as name1_0_
> from InvoiceEntry invoiceent0_ where invoiceent0_.INVOICE_FK=?
>
> Hibernate: select invoiceent0_.INVOICE_FK as INVOICE3_1_,
> invoiceent0_.id as id1_, invoiceent0_.id as id1_0_,
> invoiceent0_.INVOICE_FK as INVOICE3_1_0_, invoiceent0_.name as name1_0_
> from InvoiceEntry invoiceent0_ where invoiceent0_.INVOICE_FK=?
>
>
>
> Tušíte někdo kde by mohl být problém? Nebo je toto chování normální?
>
> Předem děkuji za odpověď.
>
> Martin Chalupa
>
Petr Ferschmann
SoftEU s.r.o.
-----------------------------------
Bolevecká 6
301 00 Plzen
Czech Republic
-----------------------------------
Phone: +420 373 731 284
+420 373 729 300
Fax: +420 373 729 301
Cell: +420 775 638 008
E-mail: [EMAIL PROTECTED]