Mapping array with Hibernate

后端 未结 4 833
谎友^
谎友^ 2020-11-29 09:53

Can you please help me to map this class using Hibernate?

public class MyClass{
    private Long id;
    private String name;
    private int[] values;
    .         


        
4条回答
  •  盖世英雄少女心
    2020-11-29 10:24

    Hibernate can map only the primitive types. Check under the org.hibernate.type folder of hibernate jar package. int array is not one of them. So you would have to write a custom type that can implement the UserType interface.

    public class MyClass{
         private Long id;
         private String name;
         private Integer[] values;
    
         @Type(type = "com.usertype.IntArrayUserType")
         public Integer[] getValues(){
             return values;
         }
    
         public void setValues(Integer[] values){
             this.values = values;
         }
     }
    

    IntArrayUserType.class

    package com.usertype.IntArrayUserType;
    
    public class IntArrayUserType implements UserType {
    
    protected static final int[] SQL_TYPES = { Types.ARRAY };
    
    @Override
    public Object assemble(Serializable cached, Object owner) throws HibernateException {
        return this.deepCopy(cached);
    }
    
    @Override
    public Object deepCopy(Object value) throws HibernateException {
        return value;
    }
    
    @Override
    public Serializable disassemble(Object value) throws HibernateException {
        return (Integer[]) this.deepCopy(value);
    }
    
    @Override
    public boolean equals(Object x, Object y) throws HibernateException {
    
        if (x == null) {
            return y == null;
        }
        return x.equals(y);
    }
    
    @Override
    public int hashCode(Object x) throws HibernateException {
        return x.hashCode();
    }
    
    @Override
    public boolean isMutable() {
        return true;
    }
    
    @Override
    public Object nullSafeGet(ResultSet resultSet, String[] names, SessionImplementor session, Object owner)
            throws HibernateException, SQLException {
        if (resultSet.wasNull()) {
            return null;
        }
        if(resultSet.getArray(names[0]) == null){
            return new Integer[0];
        }
    
        Array array = resultSet.getArray(names[0]);
        Integer[] javaArray = (Integer[]) array.getArray();
        return javaArray;
    }
    
    @Override
    public void nullSafeSet(PreparedStatement statement, Object value, int index, SessionImplementor session)
            throws HibernateException, SQLException {
        Connection connection = statement.getConnection();
        if (value == null) {
            statement.setNull(index, SQL_TYPES[0]);
        } else {
            Integer[] castObject = (Integer[]) value;
            Array array = connection.createArrayOf("integer", castObject);
            statement.setArray(index, array);
        }
    }
    
    @Override
    public Object replace(Object original, Object target, Object owner)       throws HibernateException {
        return original;
    }
    
    @Override
    public Class returnedClass() {
        return Integer[].class;
    }
    
    @Override
    public int[] sqlTypes() {
        return new int[] { Types.ARRAY };
    }
    

    When you query for the MyClass entity you can add something like this:

    Type intArrayType = new TypeLocatorImpl(new TypeResolver()).custom(IntArrayUserType.class);
    Query query = getSession().createSQLQuery("select values from MyClass")
       .addScalar("values", intArrayType);
    List results = (List) query.list();
    

提交回复
热议问题