2012-01-26 30 views
20

Sto utilizzando Hibernate 3.6.7 per eseguire il mapping dalle mie classi alle tabelle di Oracle. Io di solito non ottengo questa eccezione:org.hibernate.HibernateException: impossibile accedere al flusso lob

org.hibernate.HibernateException: Unable to access lob stream 
    at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222) 
    at java.util.concurrent.FutureTask.get(FutureTask.java:83) 
    at com.mycompany.TransferFiles.TransferFilesToHadoop(TransferFiles.java:85) 
    at com.mycompany.TransferJob.execute(TransferJob.java:25) 
    at org.quartz.core.JobRunShell.run(JobRunShell.java:202) 
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:525) 
Caused by: org.hibernate.HibernateException: Unable to access lob stream 
     at org.hibernate.type.descriptor.java.ClobTypeDescriptor.unwrap(ClobTypeDescriptor.java:117) 
    at org.hibernate.type.descriptor.java.ClobTypeDescriptor.unwrap(ClobTypeDescriptor.java:46) 
    at org.hibernate.type.descriptor.sql.ClobTypeDescriptor$3$1.doBind(ClobTypeDescriptor.java:83) 
    at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:91) 
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:283) 
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:278) 
    at org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(AbstractSingleColumnStandardBasicType.java:89) 
    at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2184) 
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2558) 
    at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2494) 
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2821) 
    at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:113) 
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273) 
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265) 
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:185) 
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) 
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51) 
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216) 
    at com.mycompany.HibernateUtil.getSession(HibernateUtil.java:36) 
    at com.mycompany.BasicDaoImpl.saveOrUpdate(BasicDaoImpl.java:34) 
    at com.mycompany.FileCopyRoutine.call(TransferFiles.java:297) 
    at com.mycompany..FileCopyRoutine.call(TransferFiles.java:225) 
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
    at java.lang.Thread.run(Thread.java:662) 
Caused by: java.sql.SQLException: Closed Connection 
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112) 
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146) 
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208) 
    at oracle.sql.CLOB.getDBAccess(CLOB.java:1196) 
    at oracle.sql.CLOB.getCharacterStream(CLOB.java:278) 
    at sun.reflect.GeneratedMethodAccessor29.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.hibernate.engine.jdbc.SerializableClobProxy.invoke(SerializableClobProxy.java:74) 
    at $Proxy2.getCharacterStream(Unknown Source) 
    at org.hibernate.type.descriptor.java.ClobTypeDescriptor.unwrap(ClobTypeDescriptor.java:114) 

Quando chiamo il metodo saveOrUpdate.

Qualcuno potrebbe darmi qualche suggerimento?

public static synchronized Session getSession() throws DBConnectionException{ 

    Session session = threadSession.get(); 

    if(session==null||!session.isOpen()||!session.isConnected()){ 
     if(sessionFactory==null||sessionFactory.isClosed())initHibernate(); 
     try{ 
      session = sessionFactory.openSession(); 
     }catch(Exception e){ 
      throw new DBConnectionException("Exception caught when trying to generate Hibernate session."); 
     } 
     threadSession.set(session); 
    } 
    if(session.isDirty()){ 
     session.flush();(36 line of HibernateUtil) 
    } 
    session.clear(); 
    return session; 
} 

Uso tutto a lungo.

ora sto trasferendo il file parallelamente e quindi aggiorno il database utilizzando il metodo saveOrUpdate.Althrough ci sono molti thread, ho sincronizzato questa parte nel mio codice. Penso che abbiamo sempre una connessione al database, ma dà l'opportunità di una connessione chiusa. Qualcuno potrebbe darmi qualche suggerimento su questa eccezione. Qual è il problema?

Ho pensato che avrebbe potuto utilizzare saveOrUpdate, quindi ho deciso di unirmi, ma sames ha lo stesso problema.

Caused by: org.hibernate.HibernateException: Unable to access lob stream 
    at org.hibernate.type.descriptor.java.ClobTypeDescriptor.unwrap(ClobTypeDescriptor.java:117) 
    at org.hibernate.type.descriptor.java.ClobTypeDescriptor.unwrap(ClobTypeDescriptor.java:46) 
    at org.hibernate.type.descriptor.sql.ClobTypeDescriptor$3$1.doBind(ClobTypeDescriptor.java:83) 
    at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:91) 
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:283) 
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:278) 
    at org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(AbstractSingleColumnStandardBasicType.java:89) 
    at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2184) 
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2558) 
    at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2494) 
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2821) 
    at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:113) 
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273) 
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265) 
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:185) 
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) 
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51) 
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216) 
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383) 
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133) 
    at mycompany.jobsrc.BasicDaoImpl.merge(BasicDaoImpl.java:52) 
    at mycompany.FileCopyRoutine.call(TransferFiles.java:301) 
    at mycompany.FileCopyRoutine.call(TransferFiles.java:226) 
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
    at java.lang.Thread.run(Thread.java:662) 
    Caused by: java.sql.SQLException: Closed Connection 
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112) 
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146) 
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208) 
    at oracle.sql.CLOB.getDBAccess(CLOB.java:1196) 
    at oracle.sql.CLOB.getCharacterStream(CLOB.java:278) 
    at sun.reflect.GeneratedMethodAccessor36.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.hibernate.engine.jdbc.SerializableClobProxy.invoke(SerializableClobProxy.java:74) 
    at $Proxy2.getCharacterStream(Unknown Source) 
    at org.hibernate.type.descriptor.java.ClobTypeDescriptor.unwrap(ClobTypeDescriptor.java:114) 
    ... 27 more 

il mio codice di unione:

public void merge(T t) throws DBConnectionException{ 
    Session session = HibernateUtil.getSession(); 
    Transaction transaction = session.beginTransaction(); 
    session.merge(t); 
    transaction.commit(); 
} 

risposta

1

mia ipotesi pura è che avete un po 'di campo che è molto grande, quindi è mappato a SQL lob. Mappare se stesso non è corretto, sospetto. Ma succede solo quando provi a salvare un'entità con un valore non nulla. Prova a salvare tutte le tue entità con campi non null nell'app uno per uno. Questo isolerà il problema.

0

Questo potrebbe essere necessario fare qualcosa con i driver JDBC come discusso in questo thread. Puoi pubblicare la versione di Oracle e la versione di jar ojdbc che stai usando nel progetto.

0

Come si utilizza il multithreading, la mia ipotesi è che si potrebbe avere qualche problema con le transazioni. Potrebbe essere perché alcune transazioni sono in qualche modo impegnate prima di aver apportato le necessarie modifiche all'oggetto. O stai provando ad accedere all'oggetto che viene salvato dal thread diverso, il che significa che l'oggetto non è nella portata della transazione.

3

Credo di averlo prima.

Quando un oggetto di grandi dimensioni (CLOB, BLOB) viene caricato da Oracle, viene restituito come riferimento a un flusso. Se il record è mappato su ibernazione e la sessione viene chiusa dopo che l'oggetto è stato caricato (quindi l'oggetto viene rimosso) il blob del campo java viene mappato per non contenere ancora i dati; quindi, quando stai cercando di salvarlo, non può funzionare perché il flusso clob/blob è sparito.

Per iniziare, provare a continuare a caricare e salvare nella stessa sessione.

Se ricordo bene, un'altra soluzione sarebbe quella di "toccare" il campo java clob/bloc mentre la sessione di caricamento è ancora aperta. Quindi i dati verranno letti dal DB. Ma è dolorosamente inefficiente (è LOB per una ragione, cioè è grande).

Un'altra opzione è dividere i dati piccoli e i lobi in due tabelle diverse e caricare i lobi solo quando necessario.

Spero che ti aiuti con la direzione.

+0

'Causato da: java.sql.SQLException: Closed Connection' nello stacktrace implica altrimenti .. – Thihara

+0

La connessione chiusa, credo, riguarda la connessione che apparteneva alla sessione utilizzata per caricare il record. Quello, sì, già chiuso quando l'oggetto viene tentato di unirsi. –

+0

Se si verifica quando si tenta di salvarlo o aggiornarlo, non può essere correlato all'inizializzazione pigro, giusto? Il problema è che il salvataggio o l'aggiornamento sta ricevendo una sessione chiusa ... – Thihara

2

Con tutta probabilità credo che ciò sia dovuto alla cattiva gestione Session . Ma senza rivedere un sacco di codice non posso dirvi qual è il problema esatto della vostra attuale implementazione.

Credo che threadSession è un ThreadLocal. Invece di fare questa operazione manualmente utilizzare

sessionFactory.getCurrentSession();

e impostare thread nel file di sospensione di configurazione.

E rendere il tuo HibernateUtil è semplice senza tutti questi controlli. Personalmente ritengo che quegli assegni coprano la cattiva gestione della Sessione e altri errori ... Ma beh, potrebbe essere solo io ...

Problemi correlati