2016-07-28 18 views
2

WildFly 10、Java EE、JPA、およびHibernateを使用しています。最近、私のアプリケーションをMySQLからPostgreSQLに移行しました。 MySQLを使用している間、私が使用して私のエンティティで画像を保存します:PSQLException:ラージオブジェクトを自動コミットモードで使用できない

@Lob 
@Basic(fetch = FetchType.LAZY) 
private byte[] image; 

をこれは素晴らしい仕事をし、MySQLは、データを格納するためにLONGBLOBを使用しました。

のPostgreSQLに切り替えた後、列の型がOIDで、画像を永続化するとき、私はこのエラーが表示されます。

Caused by: org.postgresql.util.PSQLException: Large Objects may not be used in auto-commit mode. 
at org.postgresql.largeobject.LargeObjectManager.createLO(LargeObjectManager.java:308) 
at org.postgresql.largeobject.LargeObjectManager.createLO(LargeObjectManager.java:296) 
at org.postgresql.jdbc.PgPreparedStatement.createBlob(PgPreparedStatement.java:1202) 
at org.postgresql.jdbc.PgPreparedStatement.setBlob(PgPreparedStatement.java:1243) 
at org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.setBlob(WrappedPreparedStatement.java:1157) 
at org.hibernate.type.descriptor.sql.BlobTypeDescriptor$4$1.doBind(BlobTypeDescriptor.java:112) 
at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:73) 
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:257) 
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:252) 
at org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(AbstractSingleColumnStandardBasicType.java:39) 
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2598) 
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2883) 
... 131 more 

私は、このように挿入しています:

@PersistenceContext 
EntityManager entityManager; 

... 

//Simple insert method... 
this.entityManager.persist(entity); 

そして、これは私ですpersistence.xml

<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> 
    <persistence-unit name="MyApp" transaction-type="JTA"> 
     <jta-data-source>java:jboss/datasources/PostgreSQLDS</jta-data-source> 
     <shared-cache-mode>DISABLE_SELECTIVE</shared-cache-mode> 
     <properties> 
      <property name="hibernate.enable_lazy_load_no_trans" value="true"/> 
      <property name="hibernate.cache.use_second_level_cache" 
         value="true"/> 
      <property name="hibernate.cache.use_query_cache" value="true"/> 
     </properties> 
    </persistence-unit> 
</persistence> 

私は複数回この例外に関する他の質問は、私は問題を解決することができませんでした。

One suggestionは、データを格納するエンティティを熱心に取り込めるように、データを格納するためだけにエンティティを作成して@OneToOneという関係を使用することでしたが、結果は何も変更されませんでした。

は、もう一つの提案は、Hibernateのも、何もしなかった

<property name="hibernate.connection.autocommit" value="false"/> 

...と、自動コミット無効にしました。

これがうまくいかない理由は完全に失われています。どのようにこれが非常に一般的な例外として表示されないように見える、私は完全に間違った方法で画像データを格納する作業に近づいているように感じる。これを解決するにはどうすればよいですか、データをどのように保存する必要がありますか?

+0

「イメージデータを完全に間違った方法で保存するようになっているような気がします。正しい。画像はデータベースには全く入ってはいけません – e4c5

+0

@ e4c5私の場合、別のオプションは表示されません。このアプリケーションは、複数の異なるWildFlyインストールに水平にスケーリングされます。イメージをローカルディスクに保存すると、すべてのユーザーがそのイメージにアクセスできなくなります。私がこれと戦う方法を知っている唯一の方法は、データベースを使うことです。画像はそれぞれ1MB以下です。 –

+0

ローカルディスクに格納する必要はありません。 S3、Googleファイル、または任意の数のCDNに保存できます。 – e4c5

答えて

2

これはHibernateでどのように行われているかはわかりませんが、同じデータベーストランザクション内で大きなオブジェクトを開いたり、読み書きする必要があります。

自動コミットモードを無効にすると、間違ったことがあったはずです。

大きなオブジェクトをまったく使用しないことをお勧めしますか?
通常、PostgreSQLのデータ型は最大1GBのデータを含むことができるbyteaデータ型を使う方が簡単です。大規模なオブジェクトはチャンク内にデータを格納して取得しない限り、大きな利点はありませんし、とにかくORMを使用して大きなオブジェクトの機能を完全に活用することはできません。

+0

これは例外を解決しませんが、現時点では現在私にとって最も簡単な代替ソリューションです。 'bytea'を使って' @Lob'アノテーションを削除するとうまくいきます。 –

関連する問題