2015-09-14 2 views
3

Я пытаюсь сохранить объект с полем байтового массива. Я использую Hibernate и JPA поверх базы данных MySQL. Это поле Definiton, который работал отлично для встроенной базы данных H2:Хранить массив байтов в MySQL с Hibernate

@Entity(name = "blob") 
public class Blob { 
    ... 
    @Lob 
    @Basic(fetch = FetchType.LAZY) 
    @Column(name = "blobImg", nullable = false) 
    private byte[] blobImg; 
} 

Теперь, с базой данных MySQL, генерируется исключение каждый раз я выполняю blobRepository.save(). На самом деле, может быть брошен, когда Hibernate пытается автосоздать таблицу объекта Blob. Исключением является следующее:

o.h.engine.jdbc.spi.SqlExceptionHelper : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'blob (blobCols, blobImg, blobRows, channel, idBlobPersistence) values (50, _bina' at line 1

Я попытался изменить определение поля с несколькими подходами я нашел в Интернете:

Подход 1:

@Column(name = "blobImg", nullable = false, columnDefinition = "BINARY(256)", length = 256) 
private byte[] blobImg; 

Подход 2:

@Lob 
@Column(name="blobImg", columnDefinition="bytea") 
private byte[] blobImg; 

подход 3: Определение отображения спящего режима на blob.hbm.x мл файла и отсылая его из EntityManagerFactory фасоли:

<?xml version='1.0' encoding='UTF-8'?> 
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="mappingResources"> 
     <list> 
      <value>blob.hbm.xml</value> 
     </list> 
    </property> 
</bean> 

blob.hbm.xml отображения:

<hibernate-mapping> 
    <class name="guiatv.persistence.domain.Blob" table="blob"> 
     <property name="blobImgProperty"> 
      <column name="blobImg" sql-type="binary"></column> 
     </property> 
    </class> 
</hibernate-mapping> 

подход 4: изменения blob.hbm.xml отображения на следующее:

<?xml version='1.0' encoding='UTF-8'?> 
<hibernate-mapping> 
    <class name="guiatv.persistence.domain.Blob" table="blob"> 
     <property name="blobImg" type="binary"> 
      <column name="blobImg" /> 
     </property> 
    </class> 
</hibernate-mapping> 

Все они бросают то же исключение.

Как его решить? Спасибо!

ответ

2

Ну,

Я пробовал ваши предложения @Ernusc. Первый:

@Lob(type = LobType.BLOB) 
private byte[] blobImg; 

это не компиляция для меня. Возможно, моя версия Hibernate отличается от вашей. О втором варианте:

@Type(type = "org.hibernate.type.BlobType") 
@Lob 
private byte[] blobImg; 

Он компилируется, но терпит неудачу во время выполнения.Он показывал следующее сообщение об ошибке:

2015-09-14 23:21:01.324 WARN 7436 --- [bTaskExecutor-3] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1064, SQLState: 42000 
2015-09-14 23:21:01.324 ERROR 7436 --- [bTaskExecutor-3] o.h.engine.jdbc.spi.SqlExceptionHelper : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'blob blob0_ where blob0_.idBlobPersistence=326' at line 1 
2015-09-14 23:21:01.337 INFO 7436 --- [bTaskExecutor-3] o.h.e.internal.DefaultLoadEventListener : HHH000327: Error performing load command : org.hibernate.exception.SQLGrammarException: could not extract ResultSet 

Кроме того, когда я пытался следовать след, я нашел, что это было на самом деле бросали следующее исключение:

java.lang.ClassCastException: [B cannot be cast to java.sql.Blob 

Тогда я понял, что первый из сообщений об ошибках был фактически вызван моей глупой идеей назвать мою сущность «blob», которая, вероятно, является зарезервированным ключевым словом в Hibernate. Поэтому я изменил заявление лица от:

@Entity(name = "blob") 
public class Blob { 
    ... 
} 

к:

@Entity(name = "blobframe") 
public class Blob { 
    ... 
} 

Тогда ваше второе предложение было только бросать это исключение ClassCastException. Однако некоторые из подходов, которые я пробовал до этого, теперь работают. Например:

@Column(name = "blobImg", nullable = false, columnDefinition = "BINARY(256)", length = 256) 
private byte[] blobImg; 

UPDATE: Этот подход не работает для меня. Он не будет работать на blobframe создания таблицы со следующим определением поля (не знаю причину, хотя):

@Lob 
@Column(name="blobImg", columnDefinition="bytea") 
private byte[] blobImg; 

Спасибо Ernusc за быстрый ответ.

2

Если вы хотите конвертировать ваши byte[] в SQL типа Blob, вы можете сделать следующее:

@Lob(type = LobType.BLOB) 

или

@Type(type = "org.hibernate.type.BlobType") 
@Lob 

Надеется, что это помогает

+0

Вам не нужно указывать тип LOB, он выводится из типа поля. Для массива байтов JPA автоматически предполагает, что это BLOB. Для String он принимает CLOB. – OndrejM

+0

@OndrejM интересно .... можете ли вы указать его спецификации JPA? спасибо – Ernusc

+1

@Emusc написано непосредственно в Javadoc для '@ Lob': https://docs.oracle.com/javaee/7/api/javax/persistence/Lob.html -« Тип Lob выведен из типа постоянное поле или свойство и за исключением строковых и символьных типов по умолчанию для Blob. " – OndrejM

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