org.hibernate.HibernateException: Unable to access lob stream

28,004

Solution 1

Try adding @Transactional over the service method where you are trying to access lob field object. It worked for me.

Solution 2

I believe I had this one before.

When a large object (CLOB, BLOB) is loaded from Oracle, it is returned as a reference to a stream. If the record is mapped to hibernate and the session is closed after the object is loaded (so the object becomes detached) the java field blob is mapped to is not containing the data yet; so when you're trying to save it back it cannot work with it because the clob/blob stream is gone.

For a start, try to keep loading and saving within the same session.

If I remember right, another workaround would be to "touch" the clob/bloc java field while the loading session is still open. Then the data will be read from the DB. But it is painfully inefficient (it is LOB for a reason, i.e. it is big).

Yet another option is to split the small data and lobs into two different tables, and load lobs only when needed.

Hope that helps you with the direction.

Solution 3

My pure guess is that you have some field that is very large, so it is mapped to sql lob. Mapping itself is incorrect, I suspect. But it only happens when you try to save entity with nonnull value. Try to save all your entities with nonnull fields in app one by one. This will isolate the problem.

Solution 4

In all probability I believe that this is due to Session mismanagement. But without reviewing a lot of code I cannot tell you what the exact problem of your current implementation is.

I believe threadSession is a ThreadLocal. Instead of doing this manually please use

sessionFactory.getCurrentSession();

and set thread in the hibernate config file.

And make your HibernateUtil is simple without all those checks. Personally I feel that those checks will cover up Session mismanagement and other errors... But well that may be just me...

Solution 5

If using spring, adding the following application properties make it work for us:

spring.datasource.hikari.auto-commit
Share:
28,004
lucky_start_izumi
Author by

lucky_start_izumi

Updated on April 11, 2020

Comments

  • lucky_start_izumi
    lucky_start_izumi about 4 years

    I am using hibernate 3.6.7 to do mapping from my classes to oracle tables. I don't usually get this exception:

    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)
    

    When I call saveOrUpdate method.

    Could anyone please give me some suggestion?

    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;
    }
    

    I use it all for a long time.

    now I am transferring file parallelly and then update database use saveOrUpdate method.Althrough there are many threads, I snychronized this part in my code. I think we have connection to the database all the time, but it gives excpetion of closed connection. Could anyone please give me some suggestion about this exception.What the problem should be?

    I thought it could because of using saveOrUpdate, so I changed to merge, but it sames to have the same problem.

    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
    

    my merge code:

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