2016-07-28 3 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 должен был создать объект исключительно для хранения данных и использовать связь с ним так, чтобы объект, хранящий данные, мог быть надежно извлечен, однако это никак не изменило результаты.

Другое предложение отключить библиотеки Hibernate автофиксация с

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

... который тоже не сделал ничего.

Я полностью потерял, почему это не сработает. Похоже, что это не очень распространенное исключение, я чувствую, что приближаюсь к задаче хранения данных изображения совершенно неправильно. Что я могу сделать, чтобы исправить это, или как мне хранить данные?

+0

«Я чувствую, что приближаюсь к задаче хранения данных изображения совершенно неправильно». верный. Изображений не должно быть в базе данных вообще – e4c5

+0

@ e4c5 В моем случае я не вижу другого варианта. Это приложение будет масштабироваться по горизонтали в нескольких разных установках WildFly. Если я храню изображения на локальном диске, он не будет доступен для всех пользователей. Единственный способ, которым я знаю, как бороться с этим, - это использовать базу данных. Изображения не более 1 МБ каждый. –

+0

Вам не нужно хранить на локальном диске. Вы можете хранить файлы S3, Google или любое количество CDN. Вы получите огромное повышение производительности – e4c5

ответ

2

Я не могу сказать, как это делается в спящем режиме, но открытие и чтение/запись большого объекта должны произойти в рамках одной транзакции базы данных.

Отключение режима autocommit должно делать трюк, возможно, вы сделали что-то неправильно.

Но могу ли я предположить, что вы вообще не используете большие объекты?
Обычно гораздо проще использовать тип данных PostgreSQL , который может содержать данные размером до 1 ГБ. Если вы не храните и не извлекаете данные в куски, большие объекты не предлагают никаких преимуществ, и я сомневаюсь, что вы можете полностью использовать функциональность больших объектов с ORM в любом случае.

+0

Хотя это не устраняет исключения, в настоящее время это самое простое альтернативное решение для меня на данный момент. Использование 'bytea' и удаление аннотации' @ Lob' работает хорошо. –

Смежные вопросы