Hibernate/JPA/HSQL:如何为用户类型数组创建方言映射
我已经成功地用Postgres创建了用户类型,并且可以成功地读写Hibernate/JPA/HSQL:如何为用户类型数组创建方言映射,hibernate,jpa,hsqldb,usertype,Hibernate,Jpa,Hsqldb,Usertype,我已经成功地用Postgres创建了用户类型,并且可以成功地读写 @org.hibernate.annotations.Type(type = "com.xxx.datamodel.ext.FooType" ) @Column(name = "foo", nullable = false) private int[] foo @org.hibernate.annotations.Type(type = "com.xxx.datamodel.ext.BarType" ) @Column(name
@org.hibernate.annotations.Type(type = "com.xxx.datamodel.ext.FooType" )
@Column(name = "foo", nullable = false)
private int[] foo
@org.hibernate.annotations.Type(type = "com.xxx.datamodel.ext.BarType" )
@Column(name = "bar", nullable = false)
private double[] bar
但是,当我尝试使用HSQLdial(用于单元测试)时,我得到:
这种方法的问题是,每个SQL类型只允许有一个映射,并且不能在
int[]
和double[]
之间正确解析。不确定这是否是正确的方法。也许还有其他方法可以覆盖模式创建过程?我通过解决它来解决这个问题。HSQLDB根本不支持阵列。但由于我需要做的只是序列化和反序列化我的单元测试数组,所以我可以将所有内容转换为blob
为此,我修改了UserType对象,根据是否设置了静态全局标志返回数组或Blob,设置HSQLDB时默认使用数组并使用Blob。我解决了这个问题。HSQLDB根本不支持阵列。但由于我需要做的只是序列化和反序列化我的单元测试数组,所以我可以将所有内容转换为blob
为此,我修改了UserType对象,根据是否设置了静态全局标志返回数组或Blob,这默认为使用数组,并在设置HSQLDB时使用Blob。我解决了这个问题。此时,我使用Hibernate session.doWork(…)来获取JDBC连接,并使用JDBC进行了连接: 提示:定义数组类型(在调用 connection.createArrayOf(类型名,对象[]) )有关允许的类型的名称,可以参考此源代码:
(这是这个答案的一个提示:)我解决了这个问题。此时,我使用Hibernate session.doWork(…)来获取JDBC连接,并使用JDBC进行了连接: 提示:定义数组类型(在调用 connection.createArrayOf(类型名,对象[]) )有关允许的类型的名称,可以参考此源代码:
(这是这个答案的一个提示:)同样的问题持续的时间比我想承认的要长。最终将其添加到我的测试包和特定于测试的配置文件中:
package com.example.test;
import org.hibernate.dialect.PostgreSQL9Dialect;
import java.sql.Types;
public class PostgreSQLDialectArray extends PostgreSQL9Dialect {
public PostgreSQLDialectArray() {
super();
registerHibernateType(Types.ARRAY, "array");
registerColumnType(Types.ARRAY, "integer[]" );
}
}
到目前为止,似乎正在按预期运行。同样的问题持续的时间比我想承认的要长。最终将其添加到我的测试包和特定于测试的配置文件中:
package com.example.test;
import org.hibernate.dialect.PostgreSQL9Dialect;
import java.sql.Types;
public class PostgreSQLDialectArray extends PostgreSQL9Dialect {
public PostgreSQLDialectArray() {
super();
registerHibernateType(Types.ARRAY, "array");
registerColumnType(Types.ARRAY, "integer[]" );
}
}
到目前为止,它的功能似乎与预期的一样。PostgreSQL和HSQLDB方言不映射数组类型(我见过的任何其他方言也不映射)。行为改变可能是由于JDBC驱动程序对数组类型支持的不同报告,而Hibernate希望在驱动程序支持数组类型时找到一个映射。有一点混淆:一旦创建了用户类型,Postgres方言确实支持数组:/**(非Javadoc)*@请参见org.hibernate.usertype.usertype#returnedClass()/@Override@SuppressWarnings(“未选中”)公共类returnedClass(){return Double[].Class;}/*(非Javadoc)*@请参见org.hibernate.usertype.usertype#sqlTypes()*/@Override public int[]sqlTypes(){return SQL_TYPES;//TYPES.ARRAY}@user671435什么是
SQL_TYPES
?虽然可以让Hibernate处理PostgreSQL数组,但问题是在模式生成期间PostgreSQL和HSQLDB方言不映射数组类型(我见过的任何其他方言也不映射)。行为改变可能是由于JDBC驱动程序对数组类型支持的报告不同,而Hibernate希望在驱动程序支持数组类型时找到映射。有一点混淆:一旦创建用户类型,Postgres方言确实支持数组:/**(非Javadoc)*@请参见org.hibernate.usertype.usertype#returnedClass()/@Override@SuppressWarnings(“未选中”)公共类returnedClass(){return Double[].Class;}/*(非Javadoc)*@请参见org.hibernate.usertype.usertype#sqlTypes()*/@Override public int[]sqlTypes(){return SQL_TYPES;//TYPES.ARRAY}@user671435什么是SQL_TYPES
?虽然Hibernate可以用于PostgreSQL数组,但问题是在模式生成期间HSQLDB完全支持数组,例如创建表T(arr INT ARRAY);插入到T值数组[1,2,3];
并支持PreparedStatement#setArray(inti,java.sql.Array)
。问题在于与Hibernate的交互,这需要研究和解决。我还必须创建一个自定义的Hibernate方言,扩展将Sql.ARRAY类型映射到varbinary的HSQLDB方言。HSQLDB完全支持数组,例如创建表T(arr INT ARRAY);插入到T值数组[1,2,3]
并支持PreparedStatement#setArray(int i,java.sql.Array Array)
。问题在于与Hibernate的交互,应该对此进行研究和修复。我还必须创建一个自定义Hibernate方言,该方言扩展了将sql.Array类型映射到varbinary的HSQLdialent。
package com.example.test;
import org.hibernate.dialect.PostgreSQL9Dialect;
import java.sql.Types;
public class PostgreSQLDialectArray extends PostgreSQL9Dialect {
public PostgreSQLDialectArray() {
super();
registerHibernateType(Types.ARRAY, "array");
registerColumnType(Types.ARRAY, "integer[]" );
}
}
spring:
jpa:
hibernate:
ddl-auto: create-drop
properties:
hibernate:
dialect: com.example.test.PostgreSQLDialectArray