【问题标题】:H2 database and Spring Data ignoring @Lob field annotationH2 数据库和 Spring Data 忽略 @Lob 字段注释
【发布时间】:2019-05-05 16:18:18
【问题描述】:

我正在使用 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 语句手动更改列类型,但也许有更好的解决方法?

【问题讨论】:

  • 我认为您在测试中插入的内容比列定义长。尝试删除长度并重复测试以查看默认值(应该是最大长度)是否有效。
  • 您的 H2 架构是如何生成和应用的?
  • 感谢 cmets,模式是自动创建的:hibernate.ddl-auto=update
  • 另外,你能告诉我们你的测试课吗?对你有帮助。
  • 看起来是@Column(length = 1000) 的问题,内容较长。谢谢!

标签: java spring-data h2


【解决方案1】:

如果您正在寻找跨数据库的一致性以及与 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 请求会将内容存储在数据库中,并将其与 id 为 exampleId 的示例实体相关联。

curl /examplesContent/{exampleId}

将再次获取它等等...支持完整的 CRUD。

有一些入门指南和视频here。参考指南是here

HTH

【讨论】:

    【解决方案2】:

    我在这里从 cmets 报告解决方案。您试图在该字段中插入比@Column 注释中指定的长度更长的内容。调整注释或检查您的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-29
      • 2018-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-04
      • 2012-05-19
      • 2021-06-30
      相关资源
      最近更新 更多