Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: Spring 2 with Hibernate 3 storing Blobs

  1. #1
    Join Date
    Nov 2008
    Posts
    12

    Default Spring 2 with Hibernate 3 storing Blobs

    My company has asked me to look into storing and retrieving files into a database using hibernate and spring. Up until last week I had no experience with either the spring framework or hibernate so I prototyped up a quick proof of concept application:
    Load an image file from my disk and store in the DB
    Retrieve that image from the DB and write it somewhere else to disk.

    when I try to save the domain object to disk using hibernate I get: Exception in thread "main" java.lang.IllegalStateException: Active Spring transaction synchronization or active JTA transaction with specified [javax.transaction.TransactionManager] required.

    appollogies for the many posts, despite hacking the url style URI's out of the configs it refuses to let me post them until I get over 5 posts.

  2. #2
    Join Date
    Nov 2008
    Posts
    12

    Default

    File domain Object java code
    Code:
    package springHibBlobTest;
    
    public class FileDO {
        private Long id;
        private String name;
        private byte[] fileData;
        public Long getId() {
            return id;
        }
        public void setId(Long id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public byte[] getFileData() {
            return fileData;
        }
        public void setFileData(byte[] fileData) {
            this.fileData = fileData;
        }
    }

  3. #3
    Join Date
    Nov 2008
    Posts
    12

    Default

    DAO code
    Code:
    package springHibBlobTest;
    
    import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
    
    public class TestDAO extends HibernateDaoSupport{
        
        public void saveFile(FileDO file)
        { 
          getHibernateTemplate().saveOrUpdate(file);
        }    
    
        public FileDO getFile(Long id)
        {        
            return (FileDO) getHibernateTemplate().load(FileDO.class, id);        
        }    
    }

  4. #4
    Join Date
    Jan 2008
    Location
    San Diego
    Posts
    780

    Default

    Quote Originally Posted by Draconas View Post
    when I try to save the domain object to disk using hibernate I get: Exception in thread "main" java.lang.IllegalStateException: Active Spring transaction synchronization or active JTA transaction with specified [javax.transaction.TransactionManager] required.
    Right, you need a TransactionManager. If you are just using Hibernate you can wire up a HibernateTransactionManager to your session factory or a DatasourceTransactionManager to your datasource.

    Because of how your code (below) is written, you'll probably need to add transactional aspects to your dao so that the calls get wrapped in a transaction unless you create a user transaction in your test class and manage it manually.
    Last edited by chudak; Nov 17th, 2008 at 10:39 AM.

  5. #5
    Join Date
    Nov 2008
    Posts
    12

    Default

    Main code

    Code:
    package springHibBlobTest;
    
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.beans.factory.xml.XmlBeanFactory;
    import org.springframework.core.io.FileSystemResource;
    
    
    public class Badger {
    
        /**
         * @param args
         * @throws IOException 
         */
        public static void main(String[] args) throws IOException {
            BeanFactory factory = new XmlBeanFactory(new FileSystemResource("src\\applicationContext.xml"));
          
            //creaet the file handle
            File inputfile = new File("h:\\inputtest\\input image.jpg");
            InputStream is = new FileInputStream(inputfile);
            
            //create the fileDO
            FileDO fileDO = new FileDO();
            fileDO.setName(inputfile.getName());
            
            //read in the image file to memory and store in the DO
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            try
            {
                byte[] buffer = new byte[1024];
                int bytesRead = 0;
                while ((bytesRead = is.read(buffer)) != -1)
                {
                    baos.write(buffer,0, bytesRead);
                }
                fileDO.setFileData(baos.toByteArray());
            }
            finally
            {
                is.close();
                baos.close();
            }
            
            //create the DAO
            TestDAO dao = (TestDAO) factory.getBean("fileDAO");
            
            System.out.println("started!");
            
            //save the DO        
            dao.saveFile(fileDO);
            
            //get the image back out and save it in a new location
            Long l = fileDO.getId();
                    
            FileDO recoveredFile = dao.getFile(l);
            
            File outputFile = new File("h:\\outputtest\\test.jpg");
            OutputStream os = new FileOutputStream(outputFile);              
            
            os.write(recoveredFile.getFileData());
                
            os.flush();
            os.close(); 
            System.out.println("done");
    
        }
    
    }

  6. #6
    Join Date
    Nov 2008
    Posts
    12

    Default

    Console Log
    Code:
    17-Nov-2008 15:51:28 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    INFO: Loading XML bean definitions from file [H:\workspace\SpringHibBLOBTest\src\applicationContext.xml]
    17-Nov-2008 15:51:29 org.springframework.jdbc.datasource.DriverManagerDataSource setDriverClassName
    INFO: Loaded JDBC driver: oracle.jdbc.OracleDriver
    17-Nov-2008 15:51:29 org.hibernate.cfg.Environment <clinit>
    INFO: Hibernate 3.2.6
    17-Nov-2008 15:51:29 org.hibernate.cfg.Environment <clinit>
    INFO: hibernate.properties not found
    17-Nov-2008 15:51:29 org.hibernate.cfg.Environment buildBytecodeProvider
    INFO: Bytecode provider name : cglib
    17-Nov-2008 15:51:29 org.hibernate.cfg.Environment <clinit>
    INFO: using JDK 1.4 java.sql.Timestamp handling
    17-Nov-2008 15:51:29 org.hibernate.cfg.HbmBinder bindRootPersistentClassCommonValues
    INFO: Mapping class: springHibBlobTest.FileDO -> BLOB_TEST
    17-Nov-2008 15:51:29 org.springframework.orm.hibernate3.LocalSessionFactoryBean buildSessionFactory
    INFO: Building new Hibernate SessionFactory
    17-Nov-2008 15:51:29 org.hibernate.connection.ConnectionProviderFactory newConnectionProvider
    INFO: Initializing connection provider: org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory buildSettings
    INFO: RDBMS: Oracle, version: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
    With the Partitioning, OLAP, Data Mining and Real Application Testing options
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory buildSettings
    INFO: JDBC driver: Oracle JDBC driver, version: 10.1.0.2.0
    17-Nov-2008 15:51:30 org.hibernate.dialect.Dialect <init>
    INFO: Using dialect: org.hibernate.dialect.Oracle10gDialect
    17-Nov-2008 15:51:30 org.hibernate.transaction.TransactionFactoryFactory buildTransactionFactory
    INFO: Using default transaction strategy (direct JDBC transactions)
    17-Nov-2008 15:51:30 org.hibernate.transaction.TransactionManagerLookupFactory getTransactionManagerLookup
    INFO: No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Automatic flush during beforeCompletion(): disabled
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Automatic session close at end of transaction: disabled
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Scrollable result sets: enabled
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory buildSettings
    INFO: JDBC3 getGeneratedKeys(): disabled
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Connection release mode: on_close
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Default batch fetch size: 1
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Generate SQL with comments: disabled
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Order SQL updates by primary key: disabled
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Order SQL inserts for batching: disabled
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory createQueryTranslatorFactory
    INFO: Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
    17-Nov-2008 15:51:30 org.hibernate.hql.ast.ASTQueryTranslatorFactory <init>
    INFO: Using ASTQueryTranslatorFactory
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Query language substitutions: {}
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory buildSettings
    INFO: JPA-QL strict compliance: disabled
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Second-level cache: enabled
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Query cache: disabled
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory createCacheProvider
    INFO: Cache provider: org.hibernate.cache.NoCacheProvider
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Optimize cache for minimal puts: disabled
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Structured second-level cache entries: disabled
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Statistics: disabled
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Deleted entity synthetic identifier rollback: disabled
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Default entity-mode: pojo
    17-Nov-2008 15:51:30 org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Named query checking : enabled
    17-Nov-2008 15:51:30 org.hibernate.impl.SessionFactoryImpl <init>
    INFO: building session factory
    17-Nov-2008 15:51:30 org.hibernate.impl.SessionFactoryObjectFactory addInstance
    INFO: Not binding factory to JNDI, no JNDI name configured
    started!
    Exception in thread "main" java.lang.IllegalStateException: Active Spring transaction synchronization or active JTA transaction with specified [javax.transaction.TransactionManager] required
    	at org.springframework.jdbc.support.lob.LobCreatorUtils.registerTransactionSynchronization(LobCreatorUtils.java:79)
    	at org.springframework.orm.hibernate3.support.AbstractLobType.nullSafeSet(AbstractLobType.java:185)
    	at org.hibernate.type.CustomType.nullSafeSet(CustomType.java:146)
    	at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2002)
    	at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2248)
    	at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2665)
    	at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:60)
    	at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
    	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
    	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
    	at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
    	at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    	at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
    	at org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:390)
    	at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:373)
    	at org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:686)
    	at springHibBlobTest.TestDAO.saveFile(TestDAO.java:9)
    	at springHibBlobTest.Badger.main(Badger.java:57)

  7. #7
    Join Date
    Nov 2008
    Posts
    12

    Default

    Spring config
    Code:
    <beans + Data REF for AOP elements + RED for TX elements >
    	
    	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    		<property name="driverClassName" value="oracle.jdbc.OracleDriver"></property>
    		<property name="url" value="jdbc:oracle:thin:@BADGER:BADGER:BADGER"></property>
    		<property name="username" value="BADGER"></property>
    		<property name="password" value="BADGER"></property>
    	</bean>
    	
    	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    		<property name="dataSource" ref="dataSource"/>	
    
    		<property name="hibernateProperties">
    			<props>
    				<prop key="hibernate.jdbc.batch_size">0</prop>
    				<prop key="hibernate.jdbc.use_streams_for_binary">true</prop>
    				<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
    			</props>
    		</property>
    		<property name="lobHandler">
    			<bean class="org.springframework.jdbc.support.lob.OracleLobHandler">
    				<property name="nativeJdbcExtractor">
    					<bean class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor" />
    				</property>
    			</bean>
    		</property>
    		<property name="mappingResources">
    			<list>
    				<value>FileDO.hbm.xml</value>
    			</list>
    		</property>
    	</bean>	
    	
    	<bean id="fileDAO" class="springHibBlobTest.TestDAO">
    		<property name="sessionFactory" ref="sessionFactory"></property>
    	</bean>
    	
    	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    		<property name="sessionFactory" ref="sessionFactory"/>
    	</bean>
    	
    	<bean id="testPrint" class="springHibBlobTest.TestPrint"></bean>
    			 
    	<aop:config>		
    		<aop:pointcut expression="execution(* springHibBlobTest.TestDAO.*(..))" id="DAOOperation" />
    		<aop:advisor advice-ref="txAdvice" pointcut-ref="DAOOperation" ></aop:advisor>
    		<aop:aspect ref="testPrint">
    			<aop:before method="AOPPrint" pointcut-ref="DAOOperation" ></aop:before>
    		</aop:aspect>
    	</aop:config>	
    	
    	<tx:advice id="txAdvice" transaction-manager="transactionManager">
    		<tx:attributes>
    			<tx:method name="*"  propagation="REQUIRED" />
    		</tx:attributes>
    	</tx:advice>
    	
    </beans>
    Hibernate Template
    Code:
    <hibernate-mapping package="springHibBlobTest">
      <class name="FileDO" table="BLOB_TEST">
      	<id column="ID" name="id">
      		<generator class="increment"></generator>
      	</id>
      	<property name="name" column="FILE_NAME" not-null="true"
      		type="string">
      	</property>
      	<property name="fileData" column="ACTUAL_FILE"
      		type="org.springframework.orm.hibernate3.support.BlobByteArrayType" not-null="true">
      	</property>
      </class>
    </hibernate-mapping>
    My classpath contains:
    Code:
    <classpath>
    	<classpathentry kind="lib" path="lb/Spring Framework/spring-framework-2.0.8/lib/aspectj/aspectjrt.jar"/>	
    	<classpathentry kind="src" path="src"/>
    	<classpathentry kind="lib" path="lb/ojdbc14.jar"/>
    	<classpathentry kind="lib" path="lb/Hibernate/hibernate-3.2.6.ga/hibernate-3.2/hibernate3.jar"/>
    	<classpathentry kind="lib" path="lb/Spring Framework/spring-framework-2.0.8/dist/spring.jar"/>
    	<classpathentry kind="lib" path="lb/Spring Framework/spring-framework-2.0.8/lib/jakarta-commons/commons-logging.jar"/>
    	<classpathentry kind="lib" path="lb/Spring Framework/spring-framework-2.0.8/lib/dom4j/dom4j-1.6.1.jar"/>	
    	<classpathentry kind="lib" path="lb/Hibernate/hibernate-3.2.6.ga/hibernate-3.2/lib/jta.jar"/>
    	<classpathentry kind="lib" path="lb/Hibernate/hibernate-3.2.6.ga/hibernate-3.2/lib/commons-logging-1.0.4.jar"/>
    	<classpathentry kind="lib" path="lb/Hibernate/hibernate-3.2.6.ga/hibernate-3.2/lib/commons-collections-2.1.1.jar"/>
    	<classpathentry kind="lib" path="lb/Hibernate/hibernate-3.2.6.ga/hibernate-3.2/lib/asm.jar"/>
    	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/MyEclipse 6.0"/>
    	<classpathentry kind="lib" path="lb/Hibernate/hibernate-3.2.6.ga/hibernate-3.2/lib/cglib-2.1.3.jar"/>
    	<classpathentry kind="output" path="bin"/>
    </classpath>
    It is being run from the standard run dialog in MyEclipse (where it was developed) on a java 5 compatable jre with the AspectJ weaver specified in the JRE's arguments.

    Thankyou very much for all help, as said, I am new the Spring and Hibernate so am certain that I have missed a config or library somewhere, let me know if I've missed any information that you need, anything I have configured for running the applciation is in this post, so if you see something missing, it's probably missing in the code too!

  8. #8
    Join Date
    Nov 2008
    Posts
    12

    Default

    Quote Originally Posted by chudak View Post
    Right, you need a TransactionManager. If you are just using Hibernate you can wire up a HibernateTransactionManager to your session factory or a DatasourceTransactionManager to your datasource.
    thanks for the quick reply! sorry for not having all the info up - had to post in chunks till I was over 5 posts and could drop the whole lot.

    I do have a transaction manager set up and injected with the relevant session manager - that was the first hit I found on google, when it didn't work I added the AOP bits to explicity specify transaction was required with the DAO.
    Last edited by Draconas; Nov 17th, 2008 at 10:41 AM. Reason: put datasource instead of session manager

  9. #9
    Join Date
    Nov 2008
    Posts
    12

    Default

    Quote Originally Posted by chudak View Post
    Right, you need a TransactionManager. If you are just using Hibernate you can wire up a HibernateTransactionManager to your session factory or a DatasourceTransactionManager to your datasource.

    Because of how your code (below) is written, you'll probably need to add transactional aspects to your dao so that the calls get wrapped in a transaction unless you create a user transaction in your test class and manage it manually.
    This could be me missing something but I thought that was the purpose of the <aop:> statements in the application config?

  10. #10
    Join Date
    Jan 2008
    Location
    San Diego
    Posts
    780

    Default

    Quote Originally Posted by Draconas View Post
    This could be me missing something but I thought that was the purpose of the <aop:> statements in the application config?
    Yeah, you hadn't posted that yet when I replied....

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •