我有一个返回sql数组的本机查询:
select person.id as personid, array_agg(car.model) as personscarsmodels
from person join car on person.id = car.ownerpersonid
group by person.id
为了在hibernate中添加对sql数组的支持,我添加到pom.xml:
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-52</artifactId>
<version>2.2.0</version>
</dependency>
当我配置我的自定义方言时,Hibernate将正确返回一个字符串数组:
public class CustomPostgreSQLDialect extends PostgreSQL95Dialect {
public CustomPostgreSQLDialect() {
super();
registerHibernateType(Types.ARRAY, "string-array");
}
@Override
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.contributeTypes(typeContributions, serviceRegistry);
typeContributions.contributeType(StringArrayType.INSTANCE);
}
}
问题是如何添加对两个字符串和int数组的支持,以便我可以添加类似的查询,但现在使用int数组。如果我像这样配置方言:
public class CustomPostgreSQLDialect extends PostgreSQL95Dialect {
public CustomPostgreSQLDialect() {
super();
registerHibernateType(Types.ARRAY, "string-array");
registerHibernateType(Types.ARRAY, "int-array");
}
@Override
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.contributeTypes(typeContributions, serviceRegistry);
typeContributions.contributeType(StringArrayType.INSTANCE);
typeContributions.contributeType(IntArrayType.INSTANCE);
}
}
抛出此异常:
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
答案 0 :(得分:0)
当你这样做时:
registerHibernateType(Types.ARRAY, "string-array");
registerHibernateType(Types.ARRAY, "int-array");
第二个电话实际上覆盖了第二个电话。这就是你得到错误的原因。
您只能将JDBC Type
注册到单个Hibernate Type
。因此,在您的情况下,您可以使用通用的Object[]
类型。
答案 1 :(得分:0)
另一种可能性是为数组定义自定义UserType,而不是使用hibernate-types-52
jar:
public class ArrayUserType implements UserType {
public static final String HIBERNATE_TYPE_NAME = "arrayusertype";
public static final ArrayUserType INSTANCE = new ArrayUserType();
public int[] sqlTypes() {
return new int[] { Types.ARRAY };
}
public Class<List> returnedClass() {
return List.class;
}
public boolean equals(Object x, Object y) throws HibernateException {
return x == null ? y == null : x.equals(y);
}
public int hashCode(Object x) throws HibernateException {
return x == null ? 0 : x.hashCode();
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException {
if (names != null && names.length > 0 && rs != null && rs.getArray(names[0]) != null) {
Object[] array = (Object[]) rs.getArray(names[0]).getArray();
List list = new ArrayList();
for (Object element : array) {
list.add(element);
}
return list;
}
return null;
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException {
// does not seem to be needed just for getting an array from db
throw new UnsupportedOperationException();
}
public Object deepCopy(Object value) throws HibernateException {
// does not seem to be needed just for getting an array from db
throw new UnsupportedOperationException();
}
public boolean isMutable() {
return false;
}
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
}
并以新的自定义方言注册:
public class CustomPostgreSQLDialect extends PostgreSQL95Dialect {
public CustomPostgreSQLDialect() {
super();
registerHibernateType(Types.ARRAY, ArrayUserType.HIBERNATE_TYPE_NAME);
}
@Override
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.contributeTypes(typeContributions, serviceRegistry);
typeContributions.contributeType(ArrayUserType.INSTANCE, ArrayUserType.HIBERNATE_TYPE_NAME);
}
}