Hi all;
i do not undersand a behaviour of hibernate concerning lazy loading in batch (with the attribute batch-size) of collection.
Here is my mapping files:
I have an objet LotTF which has a collection MouvementsTF
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class
name="package.dossierfiscal.LotTF"
table="LOT_TF" dynamic-update="false" dynamic-insert="false" >
<id name="id" type="java.lang.Long" column="LTF_K_NUM" >
<generator class="assigned">
</generator>
</id>
<set name="mouvementTFs" lazy="true" inverse="true" sort="unsorted"
batch-size="25">
<key column="LTF_K_NUM"/>
<one-to-many
class="package.MouvementTF"
/>
</set>
</class>
</hibernate-mapping>
The mapping file of Mouvement TF is:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class
name="package.MouvementTF"
table="MOUVEMENT_TF" dynamic-update="false" dynamic-insert="false"
where ="MTF_I_VISIB='O'" >
<composite-id>
<key-many-to-one name="lotTF"
class="package.LotTF"
column="LTF_K_NUM" />
<key-property name="codeMvt" type="java.lang.String"
column="MVT_C_CODE" />
<key-property name="valeurMajoration" type="java.util.Calendar"
column="MTF_D_VAL_MAJ" />
</composite-id>
</class>
</hibernate-mapping>
I execute then this JUnit test:
public void test2( ) throws Exception
{
Query q = getSessionCFS().createQuery("from LotTF as lot");
List lotsTF = q.list();
LotTF lotTF = (LotTF) lotsTF.get(0);
lotTF.getMouvementTFs().iterator();
}
The query q loads 3 LotTF objets.
Then, when the code 'lotTF.getMouvementTFs().iterator();', the sql query executed is
select
mouvementt0_.LTF_K_NUM as LTF_K_NUM__,
mouvementt0_.MVT_C_CODE as MVT_C_CODE__,
mouvementt0_.MTF_D_VAL_MAJ as MTF_D_VA3___,
mouvementt0_.LTF_K_NUM as LTF_K_NUM0_,
mouvementt0_.MVT_C_CODE as MVT_C_CODE0_,
mouvementt0_.MTF_D_VAL_MAJ as MTF_D_VA3_0_,
mouvementt0_.LTF_K_NUM as LTF_K_NUM0_
from MOUVEMENT_TF mouvementt0_
where mouvementt0_.LTF_K_NUM=?
whereas it should have been (thanks to the batch)
select
mouvementt0_.LTF_K_NUM as LTF_K_NUM__,
mouvementt0_.MVT_C_CODE as MVT_C_CODE__,
mouvementt0_.MTF_D_VAL_MAJ as MTF_D_VA3___,
mouvementt0_.LTF_K_NUM as LTF_K_NUM0_,
mouvementt0_.MVT_C_CODE as MVT_C_CODE0_,
mouvementt0_.MTF_D_VAL_MAJ as MTF_D_VA3_0_,
mouvementt0_.LTF_K_NUM as LTF_K_NUM0_
from MOUVEMENT_TF mouvementt0_
where mouvementt0_.LTF_K_NUM=? or
mouvementt0_.LTF_K_NUM=? or
mouvementt0_.LTF_K_NUM=?
Can anyone have an explanation, or is it an hibernate bug?
The worse is that i have an other mapping quite similar, it seems, but the batch is well executed:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class
name="package.LotIR"
table="LOT_IR" dynamic-update="false" dynamic-insert="false" >
<id name="id" type="java.lang.Long" column="LIR_K_NUM" >
<generator class="assigned">
</generator>
</id>
<set name="mouvementIRs" lazy="true" inverse="true" sort="unsorted"
batch-size="25">
<key column="LIR_K_NUM"/>
<one-to-many
class="package.MouvementIR"
/>
</set>
</class>
</hibernate-mapping>
and
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class
name="package.MouvementIR"
table="MOUVEMENT_IR" dynamic-update="false" dynamic-insert="false"
where ="MIR_I_VISIB='O'" >
<composite-id>
<key-many-to-one name="lotIR"
class="package.LotIR"
column="LIR_K_NUM"/>
<key-property name="codeMvt" type="java.lang.String"
column="MVT_C_CODE" />
<key-property name="valeurMajoration" type="java.util.Calendar"
column="MIR_D_VAL_MAJ" />
</composite-id>
</class>
</hibernate-mapping>
and the JUnit test:
public void test( ) throws Exception
{
Query q = getSessionCFS().createQuery("from LotIR as lot");
List lots = q.list();
LotIR lot = (LotIR) lots.get(0);
lot.getMouvementIRs().iterator();
}
The first query loads 5 LotIR object and the last line of code generates
select
mouvementi0_.LIR_K_NUM as LIR_K_NUM__,
mouvementi0_.MVT_C_CODE as MVT_C_CODE__,
mouvementi0_.MIR_D_VAL_MAJ as MIR_D_VA3___,
mouvementi0_.LIR_K_NUM as LIR_K_NUM0_,
mouvementi0_.MVT_C_CODE as MVT_C_CODE0_,
mouvementi0_.MIR_D_VAL_MAJ as MIR_D_VA3_0_,
mouvementi0_.LIR_K_NUM as LIR_K_NUM0_
from MOUVEMENT_IR mouvementi0_
where ((mouvementi0_.LIR_K_NUM=?) or
(mouvementi0_.LIR_K_NUM=?) or
(mouvementi0_.LIR_K_NUM=?) or
(mouvementi0_.LIR_K_NUM=?) or
(mouvementi0_.LIR_K_NUM=?))
as i expected.
Here are the java beans:
import java.io.Serializable;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
public class MouvementTF extends AbstractMouvement implements Serializable
{
private LotTF lotTF;
public LotTF getLotTF( )
{
return lotTF;
}
public void setLotTF( LotTF lotTF )
{
this.lotTF = lotTF;
}
public boolean equals( Object obj )
{
MouvementTF other = (MouvementTF) obj;
return new EqualsBuilder( ).append( getLotTF(), other.getLotTF() )
.append( getCodeMvt( ), other.getCodeMvt( ) )
.append( getValeurMajoration( ),
other.getValeurMajoration( ) ).isEquals( );
}
public int hashCode( )
{
return new HashCodeBuilder( ).append( getLotTF() ).append( getCodeMvt( ) )
.append( getValeurMajoration( ) ).toHashCode( );
}
}
import java.io.Serializable;
import java.util.Iterator;
import java.util.Set;
public class LotTF extends AbstractLot implements Serializable
{
private Set mouvementTFs;
public Set getMouvementTFs( )
{
return mouvementTFs;
}
public void setMouvementTFs( Set mouvementTFs )
{
this.mouvementTFs = mouvementTFs;
}
}
and
import java.io.Serializable;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
public class MouvementIR extends AbstractMouvement implements Serializable
{
private LotIR lotIR;
public LotIR getLotIR( )
{
return lotIR;
}
public void setLotIR( LotIR lotIR )
{
this.lotIR = lotIR;
}
public boolean equals( Object obj )
{
MouvementIR other = (MouvementIR) obj;
return new EqualsBuilder( ).append( getLotIR(), other.getLotIR() )
.append( getCodeMvt( ), other.getCodeMvt( ) )
.append( getValeurMajoration( ),
other.getValeurMajoration( ) ).isEquals( );
}
public int hashCode( )
{
return new HashCodeBuilder( ).append( getLotIR() ).append( getCodeMvt( ) )
.append( getValeurMajoration( ) ).toHashCode( );
}
}
import java.util.Iterator;
import java.util.Set;
public class LotIR extends AbstractLot
{
private Set mouvementIRs;
private Set contratIRs;
public Set getMouvementIRs( )
{
return mouvementIRs;
}
public void setMouvementIRs( Set mouvementIRs )
{
this.mouvementIRs = mouvementIRs;
}
}
Does hibernate behave randomly? Or is it my code which is wrong?
Thanks in advance for the explanation.
Jean
|