Boa tarde galera… eu estou iniciando agora com JPA a comecei a enfrentar alguns problemas… possuo uma tabela com uns 30mil registros e preciso ler um a um e fazer algum tipo de processamento… segue abaixo o codigo:
[code]public class ClasseXXX
{
private static final Logger LOG = Logger.getLogger( “logger” );
private static final Integer FETCH_SIZE = 1000;
private EntityManager em;
public void executar( )
{
List<Object> list;
Query query;
int i = 0;
list = null;
LOG.log( Level.INFO, "Inicializando o processamento dos registros..." );
while( list == null || list.size( ) > 0 )
{
LOG.log( Level.INFO, "Listando os próximos " + FETCH_SIZE + " registros." );
query = em.createNamedQuery( "ClassePOJO.listar" );
query.setMaxResults( FETCH_SIZE );
query.setFirstResult( i * FETCH_SIZE );
list = query.getResultList( );
LOG.log( Level.INFO, list.size( ) + " registro(s) encontrados." );
for( Object obj : list )
processaRegistro( obj );
i++;
}
LOG.log( Level.INFO, "Conversão dos registros executada com sucesso!" );
}
public EntityManager getEntityManager( )
{ return em; }
public void setEntityManager( EntityManager em )
{ this.em = em; }
public static void main( String[ ] args ) throws Exception
{
// Create the EntityManager
EntityManagerFactory factory = Persistence.createEntityManagerFactory( "cadsus" );
EntityManager em = factory.createEntityManager( );
ClasseXXX instancia = new ClasseXXX( );
em.getTransaction( ).begin( );
instancia.setEntityManager( em );
instancia.executar( );
em.getTransaction( ).commit( );
em.close( );
}
private void processaRegistro( Object )
{
//processa alguma coisa
}
}[/code]
algumas observacoes:
1 - o trecho de codigo
query = em.createNamedQuery( "ClassePOJO.listar" );
query.setMaxResults( FETCH_SIZE );
query.setFirstResult( i * FETCH_SIZE );
list = query.getResultList( );
foi escrito desta forma pois fazendo o createNamedQuery e setMaxResults fora do loop, ele listava todos os registros. pq? sei lah… existe forma de fazer isso?
2 - a transacao foi ativada numa tentativa frustrada de dar em.flush()
Os problemas:
1 - apos processar qse 5 mil registros, ocorre um OutOfMemory… alguem sabe me explicar pq?
2 - a coisa mais bizarra do mundo: algumas vezes o getResultList retorna mais de 1000 registros… o.O
run-single:
[TopLink Info]: 2007.08.07 10:11:24.525--ServerSession(23491286)--TopLink, version: Oracle TopLink Essentials - 2.0 (Build b41-beta2 (03/30/2007))
[TopLink Info]: 2007.08.07 10:11:24.868--Not able to detect platform for vendor name [Firebird]. Defaulting to [oracle.toplink.essentials.platform.database.DatabasePlatform]. The database dialect used may not match with the database you are using. Please explicitly provide a platform using property toplink.platform.class.name.
[TopLink Info]: 2007.08.07 10:11:25.493--ServerSession(23491286)--file:/E:/Projetos/Programa/build/classes/-database login successful
07/08/2007 10:11:25 programa.ClasseXXX executar
INFO: Inicializando a conversão dos registros...
07/08/2007 10:11:25 programa.ClasseXXX executar
INFO: Listando os próximos 1000 registros.
07/08/2007 10:11:58 programa.ClasseXXX executar
INFO: 1200 registro(s) encontrados.
07/08/2007 10:11:58 programa.ClasseXXX executar
INFO: Listando os próximos 1000 registros.
07/08/2007 10:12:30 programa.ClasseXXX executar
INFO: 1000 registro(s) encontrados.
07/08/2007 10:12:31 programa.ClasseXXX executar
INFO: Listando os próximos 1000 registros.
07/08/2007 10:13:08 programa.ClasseXXX executar
INFO: 1200 registro(s) encontrados.
07/08/2007 10:13:09 programa.ClasseXXX executar
INFO: Listando os próximos 1000 registros.
07/08/2007 10:13:33 programa.ClasseXXX executar
INFO: 1000 registro(s) encontrados.
07/08/2007 10:13:40 programa.ClasseXXX executar
INFO: Listando os próximos 1000 registros.
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at org.firebirdsql.gds.XdrInputStream.readSQLData(XdrInputStream.java:89)
[TopLink Info]: 2007.08.07 10:13:57.650--ServerSession(23491286)--file:/E:/Projetos/ADI/ADI_Conversao/CVR_CadSUS/build/classes/-cadsus logout successful
at org.firebirdsql.jgds.GDS_Impl.isc_dsql_fetch(GDS_Impl.java:1093)
at org.firebirdsql.jca.FBManagedConnection.fetch(FBManagedConnection.java:828)
at org.firebirdsql.jdbc.AbstractConnection.fetch(AbstractConnection.java:969)
at org.firebirdsql.jdbc.FBCachedFetcher.<init>(FBCachedFetcher.java:63)
at org.firebirdsql.jdbc.FBResultSet.<init>(FBResultSet.java:113)
at org.firebirdsql.jdbc.AbstractStatement.getCachedResultSet(AbstractStatement.java:568)
at org.firebirdsql.jdbc.AbstractPreparedStatement.executeQuery(AbstractPreparedStatement.java:115)
at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeSelect(DatabaseAccessor.java:711)
at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:486)
at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:437)
at oracle.toplink.essentials.threetier.ServerSession.executeCall(ServerSession.java:465)
at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:213)
at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:199)
at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeSelectCall(DatasourceCallQueryMechanism.java:270)
at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.selectAllRows(DatasourceCallQueryMechanism.java:600)
at oracle.toplink.essentials.internal.queryframework.ExpressionQueryMechanism.selectAllRowsFromTable(ExpressionQueryMechanism.java:2240)
at oracle.toplink.essentials.internal.queryframework.ExpressionQueryMechanism.selectAllReportQueryRows(ExpressionQueryMechanism.java:2206)
at oracle.toplink.essentials.queryframework.ReportQuery.executeDatabaseQuery(ReportQuery.java:774)
at oracle.toplink.essentials.queryframework.DatabaseQuery.execute(DatabaseQuery.java:609)
at oracle.toplink.essentials.queryframework.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:677)
at oracle.toplink.essentials.queryframework.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:731)
at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2219)
at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:937)
at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:909)
at oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.executeReadQuery(EJBQueryImpl.java:346)
at oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.getResultList(EJBQueryImpl.java:453)
at programa.ClasseXXX.executar(ConversaoPessoas.java:98)
at programa.ClasseXXX.main(ConversaoPessoas.java:139)
Java Result: 1
EXECUTADO COM SUCESSO (tempo total: 2 minutos 43 segundos)
Estou utilizando o netbeans 5.5.1 e o Oracle TopLink Essentials - 2.0 (Build b41-beta2)… estou usando o banco de dados firebird 1.5.4 e o driver jdbc JayBird JCA/JDBC 1.5.5…
Alguem poderia me explicar o pq desses problemas, como corrigir ou se existe alguma outra forma de listar tds os registros de uma tabela sem dar OutOfMemory? Isto é problema da jpa ou do driver JDBC?
vlws…