在没有Hibernate Annotations的情况下纠正PostgreSQL文本类型的JPA注释
我正在开发一个应用程序:
- Java 1.7
- JPA(包含在javaee-api 7.0中)
- Hibernate 4.3.8.Final
- PostgreSQL-JDBC 9.4-1200-jdbc41
- PostgreSQL 9.3.6
我想将PostgreSQL文本数据类型用于某些String属性。 据我所知,在JPA中,这应该是正确的注释,在PostgreSQL中使用文本:
@Entity public class Product{ ... @Lob private String description; .... }
当我像这样注释我的实体时,我会遇到如下错误: http : //www.shredzone.de/cilla/page/299/string-lobs-on-postgresql-with-hibernate-36.html
简而言之:看起来hibernate和jdbc并不是clob / text-types的结合。
描述的解决方案正在运行:
@Entity public class Product{ ... @Lob @Type(type = "org.hibernate.type.TextType") private String description; ... }
但这有一个明显的缺点:源代码在编译时需要hibernate,这应该是不必要的(这是首先使用JPA的一个原因)。
另一种方法是使用这样的列注释:
@Entity public class Product{ ... @Column(columnDefinition = "text") private String description; ... }
哪个效果很好,但是:现在我坚持使用具有文本类型的数据库(也称为文本;))如果将来会使用另一个数据库,注释很容易被忽略。 因此,可能很难找到可能的错误,因为数据类型是在String中定义的,因此在运行时之前无法找到。
有没有解决方案,这很容易,我只是看不到它? 我非常确定我不是唯一一个将JPA与Hibernate和PostgreSQL结合使用的人。 所以我有点困惑,我找不到更多这样的问题。
只是为了完成这个问题,persistence.xml看起来像这样:
org.hibernate.ejb.HibernatePersistence com.app.model.Product
更新:
-
这个问题或多或少等同于这个问题,选择的答案是在这个问题中描述的第二种方式,由于hibernate运行时依赖性我不喜欢它: 在Postgresql中存储任意长度的字符串
-
这似乎与以下内容有关: https : //hibernate.atlassian.net/browse/JPA-48
由于text
类型不是SQL标准的一部分,因此我猜没有正式的JPA方式。
但是, text
类型与varchar
非常相似,但没有长度限制。 您可以使用@Column
的length
属性提示JPA实现:
@Column(length=10485760) private String description;
更新: 10 MiB似乎是postgresql中varchar
的最大长度。 根据文件 ,该text
几乎是无限的:
在任何情况下,可存储的最长字符串大约为1 GB。
如果你想使用普通的JPA,你可以在Dialect上重新映射使用过的CLOB类型,如下所示:
public class PGSQLMapDialect extends PostgreSQL9Dialect { @Override public SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) { if (Types.CLOB == sqlTypeDescriptor.getSqlType()) { return LongVarcharTypeDescriptor.INSTANCE; } return super.remapSqlTypeDescriptor(sqlTypeDescriptor); } }
因此,它不会使用JDBC驱动程序中的CLOB映射,该驱动程序使用OID作为列,并通过大对象处理存储/加载文本。 这只会导致通过VarcharTypeDescriptor类在Postgres JDBC驱动程序的createt文本列上调用setString和getString。
我会使用简单的private String description;
。 如果从代码生成数据库,则列类型只是一个问题,因为它将生成为varchar
而不是text
。
以数据库无关的方式编写代码是很棒的,并且没有任何JPA供应商特定的东西,但有些情况下这是不可能的。 如果现实是您必须支持多种数据库类型及其所有细节,那么您必须在某处对这些细节进行说明。 一种选择是使用columnDefinition
来定义列类型。 另一种方法是保持代码不变,只需更改数据库中的列类型即可。 我更喜欢第二个。
- 密钥’PRIMARY’的重复条目’string1-string2′
- Hibernate:级联类型
- 为hibernate 3.6配置pom.xml
- 使用hibernate标准,有没有办法逃避特殊字符?
- 如何在Tomcat中使用Hibernate支持的JPA运行Spring 3.0 PetClinic
- Spring – slf4J:如何自动记录错误和exception?
- 如何使用Hibernate注释将Java日期映射到mysql中的DATETIME(默认情况下为TIMESTAMP)
- @JoinFormula和@OneToMany定义 – 糟糕的文档
- Hibernate PersistentSet remove()操作不起作用