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

Thread: ??? Large Objects may not be used in auto-commit mode

  1. #1
    Join Date
    Jun 2005
    Posts
    5

    Default ??? Large Objects may not be used in auto-commit mode

    Hi,

    I'm using spring 1.2.1, hibernate 3.x and postgres 8.x.
    I've problem when trying to retrieve an instance of a class containing a java.sql.Blob field.
    I've tested outside spring (using Hibernate SessionFactory), it works fine and the content of my Blob is correct.

    From within spring, i'm getting the following postgres exception:

    Code:
    org.postgresql.util.PSQLException: Large Objects may not be used in auto-commit mode.
    	at org.postgresql.largeobject.LargeObjectManager.open(LargeObjectManager.java:172)
    	at org.postgresql.largeobject.LargeObjectManager.open(LargeObjectManager.java:158)
    	at org.postgresql.jdbc2.AbstractJdbc2Blob.<init>&#40;AbstractJdbc2Blob.java&#58;26&#41;
    	at org.postgresql.jdbc3.AbstractJdbc3Blob.<init>&#40;AbstractJdbc3Blob.java&#58;20&#41;
    	at org.postgresql.jdbc3.Jdbc3Blob.<init>&#40;Jdbc3Blob.java&#58;20&#41;
    	at org.postgresql.jdbc3.Jdbc3ResultSet.getBlob&#40;Jdbc3ResultSet.java&#58;54&#41;
    	at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getBlob&#40;AbstractJdbc2ResultSet.java&#58;312&#41;
    	at org.hibernate.type.BlobType.get&#40;BlobType.java&#58;56&#41;
    	at org.hibernate.type.BlobType.nullSafeGet&#40;BlobType.java&#58;110&#41;
    	at org.hibernate.type.AbstractType.hydrate&#40;AbstractType.java&#58;80&#41;
    	at org.hibernate.persister.entity.BasicEntityPersister.hydrate&#40;BasicEntityPersister.java&#58;1699&#41;
    	at org.hibernate.loader.Loader.loadFromResultSet&#40;Loader.java&#58;925&#41;
    	at org.hibernate.loader.Loader.instanceNotYetLoaded&#40;Loader.java&#58;876&#41;
    	at org.hibernate.loader.Loader.getRow&#40;Loader.java&#58;789&#41;
    	at org.hibernate.loader.Loader.getRowFromResultSet&#40;Loader.java&#58;295&#41;
    	at org.hibernate.loader.Loader.doQuery&#40;Loader.java&#58;389&#41;
    	at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections&#40;Loader.java&#58;208&#41;
    	at org.hibernate.loader.Loader.loadEntity&#40;Loader.java&#58;1278&#41;
    I've tried to configure my spring SessionFactory in order to set autocommit to false, but it didn't change a thing.

    Code:
    	<!-- Hibernate SessionFactory -->
    	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    		<property name="dataSource"><ref local="dataSource"/></property>
    		<property name="mappingResources">
    			<value>com/core/model/model.hbm.xml</value>
    		</property>
    		<property name="hibernateProperties">
    			<props>
    				<prop key="hibernate.dialect">$&#123;hibernate.dialect&#125;</prop>
    				<prop key="hibernate.show_sql">$&#123;hibernate.show_sql&#125;</prop>
    				<prop key="hibernate.connection.release_mode">on_close</prop> 
    				<prop key="hibernate.connection.autocommit">false</prop>
    			</props>
    		</property>
    	</bean>
    Any idea?
    Thanks in advance.

    Michaël.

  2. #2
    Join Date
    Jun 2005
    Posts
    9

    Default

    It says exactly what it is: in PostgreSQL, you have to put your blob-access code inside a transaction. This is RDBMS specific requirement, has nothing to do with Spring nor Hibernate.

  3. #3
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    For future PostgreSQL problems do a quick search on HB forums - it worked for me every time.
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  4. #4
    Join Date
    Jun 2005
    Posts
    5

    Default

    I've installed & configured a mySQL server...everything runs ok!

    It seems that spring set the auto-commit to false, whatever the configuration you use...

    hum...strange, isn't it?

  5. #5
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    It seems that spring set the auto-commit to false, whatever the configuration you use...
    1. I think that you can configure this aspect.
    2. If it's unconfigurable then for sure there is a good reason for it.
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  6. #6
    Join Date
    Mar 2011
    Posts
    18

    Question lazy loading LOB access on web controller invoked by POST parameter

    I've got a problem that matches this thread:

    Spring 3.0.5
    postgreSQL 8.4
    hibernate 3.x

    I want to use that nice RESTful web controller mechanism with a POST request writing into a @Lob @Basic property in an entity object in a Map<String, DocumentContent>.
    Because postgreSQL-driver wants me to open a transaction when loading LOB map contents sending POST data (languageContents['1'].)content['content'].content=sth produces the following exception:
    Code:
    org.springframework.beans.InvalidPropertyException: Invalid property 'languageContents[1].contents[content]' of bean class [de.algorythm.cmf.model.entity.Document]: Illegal attempt to get property 'contents' threw exception; nested exception is org.hibernate.exception.GenericJDBCException: could not initialize a collection: [de.algorythm.cmf.model.entity.DocumentLanguageContent.contents#1]
    	at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:827)
    ...
    Caused by: org.hibernate.exception.GenericJDBCException: could not initialize a collection: [de.algorythm.cmf.model.entity.DocumentLanguageContent.contents#1]
    	at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:140)
    ...
    Caused by: org.postgresql.util.PSQLException: LargeObjects (LOB) dürfen im Modus 'auto-commit' nicht verwendet werden.
    	at org.postgresql.largeobject.LargeObjectManager.open(LargeObjectManager.java:200)
    	at org.postgresql.largeobject.LargeObjectManager.open(LargeObjectManager.java:172)
    	at org.postgresql.jdbc2.AbstractJdbc2BlobClob.<init>(AbstractJdbc2BlobClob.java:47)
    	at org.postgresql.jdbc2.AbstractJdbc2Clob.<init>(AbstractJdbc2Clob.java:25)
    	at org.postgresql.jdbc3.AbstractJdbc3Clob.<init>(AbstractJdbc3Clob.java:20)
    	at org.postgresql.jdbc3.Jdbc3Clob.<init>(Jdbc3Clob.java:18)
    	at org.postgresql.jdbc3.Jdbc3ResultSet.getClob(Jdbc3ResultSet.java:43)
    	at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getClob(AbstractJdbc2ResultSet.java:384)
    	at org.apache.commons.dbcp.DelegatingResultSet.getClob(DelegatingResultSet.java:568)
    	at org.apache.commons.dbcp.DelegatingResultSet.getClob(DelegatingResultSet.java:568)
    	at org.hibernate.type.descriptor.sql.ClobTypeDescriptor$2.doExtract(ClobTypeDescriptor.java:70)
    	at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:64)
    	at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:253)
    	at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:249)
    	at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:229)
    	at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:330)
    	at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2265)
    	at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1527)
    	at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1455)
    	at org.hibernate.loader.Loader.getRow(Loader.java:1355)
    	at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:611)
    	at org.hibernate.loader.Loader.doQuery(Loader.java:829)
    	at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
    	at org.hibernate.loader.Loader.loadCollection(Loader.java:2166)
    	... 85 more
    My Entities look as follows:
    Code:
    @Entity
    public class Document {
    
    	@OneToMany(mappedBy="document", targetEntity=DocumentLanguageContent.class, cascade={CascadeType.REMOVE})
    	@MapKey(name="language")
    	private Map<Language, DocumentLanguageContent> languageContents;
    
    	// @id, getter, setter ...
    }
    
    @Entity
    public class DocumentLanguageContent {
    
    	@OneToMany(cascade={CascadeType.REMOVE})
    	@MapKey(name="name")
    	private Map<String, DocumentContent> contents;
    
    	// @id, getter, setter ...
    }
    
    @Entity
    public class DocumentContent {
    
    	@Lob
    	@Basic
    	private String content;
    	@Version
    	private int version;
    
    	// @id, getter, setter ...
    }
    The Controller:
    Code:
    @RequestMapping("/system/{type}")
    @Controller
    public class CrudController {
    
    	@RequestMapping(method = RequestMethod.POST)
    	@Transactional
    	public String edit(@PathVariable("type") final String type,
    			@ModelAttribute("command") @Valid Object entity, 
    			BindingResult result, Model model,
    			HttpServletRequest req)
    			throws Exception {
    		//...
    	}
    	// ...
    }
    My OR-Mapper config in applicationContext.xml:
    Code:
    <bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
            <property name="driverClassName" value="${database.driverClassName}"/>
            <property name="url" value="${database.url}"/>
            <property name="username" value="${database.username}"/>
            <property name="password" value="${database.password}"/>
        </bean>
    	<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
    		<property name="entityManagerFactory" ref="entityManagerFactory"/>
    	</bean>
    	<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
    		<property name="dataSource" ref="dataSource"/>
    	</bean>
        <tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
    I know that probably this is not the most performant way but I am implementing an annotation-driven form generator. Reference types in backend form entities that have no backend defined by configuration are part of parent entity's form.
    Simply, the target is to get a form generated for every wanted entity at any cost which can be modified later.
    Needless to say: this is academic.

    To solve this problem I could open a transaction and read the map without problems but the map is read by the spring framework right before my controller method is called with the command so that I cannot open a transaction.
    Probably, I haven't understand the spring concept but sending map values as URL parameter is supported so I am assuming this use case should also work?!

    Edit: Of course, I could and should CRUD referenced entities in an extra controller. Hibernate validator can guarantee back references are not nullable.
    But this would result in having problems with forms and sub forms with different actions.
    BUT if I have an embeddable object referenced at such entity I cannot CRUD it directly with a controller. The @Version field is the only reason why DocumentContent is an entity in this case. Else it would be annotated with @Embeddable. If we have this case we are stuck on the described problem!

    Is there any way to solve this problem? Help, please!!!

    regards,
    Max
    Last edited by MaxMan; Apr 17th, 2011 at 06:53 AM. Reason: @Embeddable

  7. #7
    Join Date
    Mar 2011
    Posts
    18

    Unhappy Help, please

    * push *

    Help, please!

  8. #8
    Join Date
    Apr 2011
    Posts
    107

    Default

    Quote Originally Posted by MaxMan View Post
    * push *

    Help, please!
    Not sure it helps...

    But, where are you scanning your controller?
    In spring-mvc configuration file or in Spring configuration file ?

    If in spring-mvc configuration file, i'm not sure @Transactional is correctly handled.

  9. #9
    Join Date
    Mar 2011
    Posts
    18

    Default

    The controller is defined by annotation. @Transactional works. But annotating a controller method with @Transactional doesn't help because the exception is thrown when lazy loading the map when spring wants to write URL parameters to command. After spring would have done this my controller method is called. So I want to know if there is some tricky configuration issue or else to make spring assign that url values in a transaction or open a transaction when lazy loading associations.

    So far I understand: If this problem cannot be solved one would not be able to save @LOB annotated properties in @Embeddable elements by URL parameter with postgreSQL driver without loading the specific properties in a transaction in a @ModelAttribute annotated method.

    regards,
    Max
    Last edited by MaxMan; Apr 18th, 2011 at 10:49 AM.

  10. #10
    Join Date
    Apr 2011
    Posts
    107

    Default

    You may take a look at "OpenSessionInViewFilter" (I know it exist, I never use it)

Similar Threads

  1. Replies: 1
    Last Post: Jun 24th, 2007, 10:58 AM
  2. Replies: 2
    Last Post: Oct 10th, 2005, 05:12 PM
  3. Replies: 3
    Last Post: Aug 4th, 2005, 01:34 PM
  4. Spring/Hibernate Delete/Update Problem
    By Noname in forum Data
    Replies: 4
    Last Post: Jun 15th, 2005, 11:07 PM
  5. Should Business Objects have References to DAOs?
    By sethladd in forum Architecture
    Replies: 9
    Last Post: Aug 25th, 2004, 01:18 PM

Posting Permissions

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