我正在使用 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 语句来手动更改列类型,但也许有更好的解决方法?
最佳答案
如果您正在寻找跨数据库的一致性以及类似于 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
@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
接口(interface)并为 JPA 注入(inject)该接口(interface)的实现。它还将注入(inject)一个将 http 请求转发到该实现的 @Controller
。这使您不必自己实现任何这些。
所以...
curl -X POST/examplesContent/{exampleId}
使用 multipart/form-data 请求会将内容存储在数据库中,并将其与 ID 为 exampleId
的示例实体关联起来。
curl/examplesContent/{exampleId}
将再次获取它等等...支持完整的 CRUD。
HTH
关于java - H2数据库和Spring Data忽略@Lob字段注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53609547/