This forum is now a read-only archive. All commenting, posting, registration services have been turned off. Those needing community support and/or wanting to ask questions should refer to the Tag/Forum map, and to http://spring.io/questions for a curated list of stackoverflow tags that Pivotal engineers, and the community, monitor.

AnnouncementAnnouncement Module

Collapse

No announcement yet.

??? Large Objects may not be used in auto-commit modePage Title Module

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

Jun 27th, 2005, 08:58 AM

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&#58; Large Objects may not be used in auto-commit mode.
at org.postgresql.largeobject.LargeObjectManager.open&#40;LargeObjectManager.java&#58;172&#41;
at org.postgresql.largeobject.LargeObjectManager.open&#40;LargeObjectManager.java&#58;158&#41;
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.

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

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!

Comment

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.