База данных H2 и Spring Data игнорируют аннотацию поля @Lob - PullRequest
0 голосов
/ 04 декабря 2018

Я работаю с базой данных MySQL и Spring Data, где у меня есть столбец, определенный следующим образом:

    @Lob
    @Column(length = 1000)
    private String messageContent;

Этот столбец используется для хранения больших строк.Он прекрасно работает с MySQL, но для модульных тестов я использую базу данных H2.Похоже, H2 игнорирует аннотацию @Lob, и я получаю:

Caused by: java.sql.SQLDataException: data exception: string data, right truncation;  table: MESSAGE column: MESSAGE_CONTENT
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCPreparedStatement.fetchResult(Unknown Source)
    at org.hsqldb.jdbc.JDBCPreparedStatement.executeUpdate(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114)
    at com.sun.proxy.$Proxy189.executeUpdate(Unknown Source)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:204)
    ... 147 common frames omitted
Caused by: org.hsqldb.HsqlException: data exception: string data, right truncation;  table: MESSAGE column: MESSAGE_CONTENT
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.Table.enforceTypeLimits(Unknown Source)
    at org.hsqldb.Table.generateAndCheckData(Unknown Source)
    at org.hsqldb.Table.insertSingleRow(Unknown Source)
    at org.hsqldb.StatementDML.insertRowSet(Unknown Source)
    at org.hsqldb.StatementInsert.getResult(Unknown Source)
    at org.hsqldb.StatementDMQL.execute(Unknown Source)
    at org.hsqldb.Session.executeCompiledStatement(Unknown Source)
    at org.hsqldb.Session.execute(Unknown Source)
    ... 156 common frames omitted

Я не могу изменить определение столбца, H2 используется только для тестовых случаев.Я думаю об изменении типа столбца вручную, выполнив инструкцию ALTER TABLE, но, может быть, есть лучший обходной путь?

Ответы [ 2 ]

0 голосов
/ 06 декабря 2018

Если вы ищете согласованность между базами данных, а также подход Spring Data к контенту, связанному с сущностями Spring Data, то почему бы не взглянуть на Spring Content JPA ?Как и Spring Data, он обеспечивает абстракцию и простую, продуманную модель программирования для ваших потребностей в контенте.Вы можете добавить его следующим образом: -

pom.xml

   <!-- Java API -->
   <dependency>          
      <groupId>com.github.paulcwarren</groupId>
      <artifactId>spring-content-jpa</artifactId>
      <version>0.4.0</version>
   </dependency>
   <!-- REST API -->
   <dependency>
      <groupId>com.github.paulcwarren</groupId>
      <artifactId>spring-content-rest</artifactId>
      <version>0.4.0</version>
   </dependency>

Конфигурация

@Configuration
@EnableJpaStores
@Import("org.springframework.content.rest.config.RestConfiguration.class")
public class ContentConfig {

   @Value("/org/springframework/content/jpa/schema-drop-h2.sql")
   private Resource dropReopsitoryTables;

   @Value("/org/springframework/content/jpa/schema-h2.sql")
   private Resource dataReopsitorySchema;

   @Bean
   DataSourceInitializer datasourceInitializer() {
     ResourceDatabasePopulator databasePopulator =
            new ResourceDatabasePopulator();

     databasePopulator.addScript(dropReopsitoryTables);
     databasePopulator.addScript(dataReopsitorySchema);
     databasePopulator.setIgnoreFailedDrops(true);

     DataSourceInitializer initializer = new DataSourceInitializer();
     initializer.setDataSource(dataSource());
     initializer.setDatabasePopulator(databasePopulator);

     return initializer;
   }
}

Чтобы связать контент, добавьте аннотации Spring Content к своей учетной записи.

Example.java

@Entity
public class Example {

   // replace @Lob field with

   @ContentId
   private String contentId;

   @ContentLength
   private long contentLength = 0L;

   // if you have rest endpoints
   @MimeType
   private String mimeType = "text/plain";

Создайте «хранилище»:

ExampleStore.java

@StoreRestResource(path="examplesContent")
public interface ExampleStore extends ContentStore<Example, String> {
}

Это все, что вам нужно для создания конечных точек REST @ /examplesContent.Когда ваше приложение запускается, Spring Content проверит ваши зависимости (см. Spring Content JPA / REST), взглянет на ваш ExampleStore интерфейс и внедрит реализацию этого интерфейса для JPA.Он также внедрит @Controller, который перенаправляет http-запросы к этой реализации.Это избавляет вас от необходимости реализовывать все это самостоятельно.

Итак ...

curl -X POST /examplesContent/{exampleId}

с запросом multipart / form-data сохранит содержимое в базе данных и свяжет его с примером объекта, идентификатор которого равенexampleId.

curl /examplesContent/{exampleId}

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

Существует несколько руководств и видео по началу работы здесь .Справочное руководство - здесь .

HTH

0 голосов
/ 04 декабря 2018

Я сообщаю решение здесь из комментариев.Вы пытаетесь вставить в это поле содержимое, длина которого превышает длину, указанную в аннотации @Column.Либо скорректируйте аннотацию, либо проверьте свой контент.

...