Hi there !! Shouldn't hibernate fill collections lazily with proxies ? then perform n selects while iterating ? When I iterate thorugh items in the collections, hibernate first hidrates all objects non lazily !!
Here's a small example of my problem:
Beans: Most of my beans have the same kind of annotations with pretty much the same parameters of cascading, here are some examples used in the fragment code below:
Code:
@SequenceGenerator(
name="SEQ_CURSO_ID",
sequenceName="curso_id_seq"
)
@Entity
@Table(name="curso")
@Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE )
public class Curso extends GenericAbstractBean {
private static Logger log = Logger.getLogger( Curso.class ) ;
// // ------------------------------------------------------------------
@Id
@GeneratedValue( strategy = GenerationType.SEQUENCE , generator = "SEQ_CURSO_ID" )
@Column (name="id")
private int id ;
public int getId() { return id ; }
public void setId( int anId ) { id = anId ; }
// // ------------------------------------------------------------------
@OneToMany(mappedBy="curso", cascade = { CascadeType.REMOVE , CascadeType.PERSIST } )
private Collection<Grupo> grupos ;
@Clonable(ClonableCascadeType.CLONE_CHILD_CASCADED)
public Collection<Grupo> getGrupos() { return grupos ; }
public void setGrupos( Collection<Grupo> unosGrupos ) { grupos = unosGrupos ; }
// // ------------------------------------------------------------------
/* and many, many other fields, using the very same
@OneToMany(mappedBy="<property>", cascade = { CascadeType.REMOVE , CascadeType.PERSIST } )
and
@ManyToOne @JoinColumn(name="<property>")
or regular columns */
}
Code:
@SequenceGenerator(
name="SEQ_GRUPO_ID",
sequenceName="grupos_id_seq"
)
@Entity
@Table(name="grupos")
@Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE )
public class Grupo extends GenericAbstractBean implements Comparable<Grupo> {
// ---------------------------------------------------------------------
@Id
@GeneratedValue( strategy = GenerationType.SEQUENCE , generator = "SEQ_GRUPO_ID" )
@Column (name="id") private int id ; ;
public int getId() { return id ; }
public void setId( int anId ) { id = anId ; }
// ---------------------------------------------------------------------
@ManyToOne
@JoinColumn(name="curso")
private Curso curso ;
public Curso getCurso() { return curso ; }
public void setCurso( Curso unCurso ) { curso = unCurso ; }
// ---------------------------------------------------------------------
/* and many, many other fields, using the very same
@OneToMany(mappedBy="<property>", cascade = { CascadeType.REMOVE , CascadeType.PERSIST } )
and
@ManyToOne @JoinColumn(name="<property>")
or regular columns */
}
... regular beans, no fancy stuff.
... most of my beans are pretty much the same, there are 74 beans.
... the problem is when iterating the collection, look at the code and the log output:
Code:
log.debug("@ Obteniendo grupos ...") ;
resultGrupos = (List<Grupo>) curso.getGrupos() ;
log.debug("@ Iterando grupos ...") ;
for( Grupo grupo : resultGrupos ) {
log.debug("@ Analizando grupo ...") ;
// some stuff
}
... this generates this output:
Code:
2006-11-16 13:46:18,673 DEBUG [paquete.SincronizarSalas] @ Obteniendo grupos ...
2006-11-16 13:46:18,673 DEBUG [paquete.SincronizarSalas] @ Iterando grupos ...
2006-11-16 13:46:18,673 DEBUG [org.hibernate.SQL] <A BIG HUUGE QUERY THAT FETCHES 29 DIFFERENT OBJECT TYPES !! 358 Columns in like 25 joins !! >
2006-11-16 13:46:18,706 DEBUG [paquete.SincronizarSalas] @ Analizando grupo ...
... and then, no more Queries are issued throug the whole iteration : (
... tried using an iterator instead of java5 "enhanced" loop, same result. How do I iterate through collection contents without hidrating the whole thing at once ?
... persistence.xml has caching, using ehcache
Code:
<persistence>
<persistence-unit name="XXXXXXX" transaction-type="JTA">
<jta-data-source>java:/XXXXXDS</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.default_schema" value="cursofeliz" />
<property name="hibernate.connection.release_mode" value="after_statement" />
<property name="hibernate.transaction.flush_before_completion" value="true" />
<property name="hibernate.transaction.auto_close_session" value="true" />
<property name="hibernate.connection.autocommit" value="true" />
<property name="javax.persistence.transactionType" value="JTA" />
<property name="jboss.entity.manager.factory.jndi.name" value="java:/EntityManagerFactories/AVACursosPersistence"/>
<property name="jboss.entity.manager.jndi.name" value="java:/EntityManagers/AVACursosPersistence"/>
<property name="hibernate.jdbc.use_streams_for_binary" value="true" />
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup" />
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.generate_statistics" value="true" />
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
</properties>
</persistence-unit>
</persistence>
... the main problem is that every once in a while queries are too big, that postgres driver rejects them and throws an exception
SQL Error: 0, SQLState: 54000 ERROR: target lists can have at most 1664 entries with a query that fetched 1799 columns from 121 joins
... any idea for a workaround ? ... a fix ? ... a patch ? ... something for my sadness ?
Hibernate version: 3.1.2
Mapping documents: Java5 Annotations
Name and version of the database you are using: PostgreSQL 8