有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Hibernate+PostgreSQL+网络地址类型(inet、cdir)

我已经用Hibernate 4.2.7和PostgreSQL 9.3.1开始了我的示例项目,一切都很顺利

目前我想使用INET PostgreSQL type,但我无法用Hibernate映射它

我遇到了这个休眠错误:无法确定以下列的类型:inet,at table:DEVICE\u IP\u ADDRESS

我使用组织。冬眠地方话PostgreSql方言和hbm。xml配置文件

我的hibernate映射文件:

<property name="ipAddress" type="inet">
     <column name="IP_ADDRESS" not-null="true" />
</property>

我问了谷歌,但找不到任何可用的解决方案。 你能帮我吗

谢谢

编辑: 如果我想使用'extra'postgresql类型和PostGIS类型,你认为我需要使用什么样的ORM实现

或者我需要使用简单的JDBC


共 (1) 个答案

  1. # 1 楼答案

    我只是解决了一个像你这样的问题。关于这件事几乎没有什么消息。正如@ms03所说。。。更好的方法是创建一个新类型和一个实现该类型的类,并处理用于设置/获取数据库的java对象

    首先,在实体上,必须为参数声明类型

    @Entity
    @Table(name="user_app")
    @TypeDefs(value={@TypeDef(name="convertInet",typeClass=PgInetType.class),
             @TypeDef(name="convertMacaddr",typeClass=PgMacaddrType.class)})
    public class User implements Serializable {
    
        //some parameters
    
      @Type(type="convertMacaddr")
      private PgMacaddr mac;
    
      @Type(type="convertInet")
      private PgInet ip;
    
         //getters and setters, equals, hashcode, toString
      }
    

    第二,为java创建新的处理对象,它必须有一个默认的构造,一个从DB处理数据的构造,并且可以序列化

    public class PgInet implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    private String address;
    
    public PgInet(String address){
        this.address=address;
    }
    
    public PgInet(){
        this.address=null;
    }
    
        //Getters,setters,hashcode, equal and toString
     }
    

    最后一步,您必须创建一个自定义类型

    public class PgInetType implements UserType{
    
    @Override
    public int[] sqlTypes() {
    
                //Because inet,macaddr,cdir...and unkwon type for java, yo must
                // define Types.OTHER
        return new int[] { Types.OTHER };
    }
    
    @Override
    public Class returnedClass() {
    
                //Object created to be handled for java
        return PgInet.class;
    }
    
    @Override
    public boolean equals(Object x, Object y) throws HibernateException {
        return ObjectUtils.nullSafeEquals(x, y);
    }
    
    @Override
    public int hashCode(Object x) throws HibernateException {
        if(x!=null)
            return x.hashCode();
        else
            return 0;
    }
    
    @Override
    public Object nullSafeGet(ResultSet rs, String[] names,
            SessionImplementor session, Object owner)
            throws HibernateException, SQLException {
    
                //Translation from DB to Java
        PgInet address=null;
    
        String ip=rs.getString(names[0]);
    
        if(ip!=null){
            address=new PgInet(ip);
        }
    
        return address;
    }
    
    @Override
    public void nullSafeSet(PreparedStatement st, Object value, int index,
            SessionImplementor session) throws HibernateException, SQLException {
    
        //Translation from java to DB
    
        if(value==null){
            st.setNull(index, Types.VARCHAR);
        }else{
    
                    //As inet,macaddr,cdir...are new types object on Postgresql you must
                    //create the specific postgresql object and to insert it
    
                    //I created 2 new cast on postgresql: inet As varchar, varchar AS inet
                    //but I think it's not neccesary because macaddr type works fine without
                    //postgresl casting
    
            st.setObject(index, getInet(value, st.getConnection()));
        }
    
    }
    
    private Object getInet(Object value, Connection connection) {
    
               //Expected object on postgresql
    
           Object tempInet = null;
           ClassLoader connectionClassLoader = connection.getClass().getClassLoader();
    
           try {
    
               //Class which will create the postgresql
    
               Class aPGObjectClass =connectionClassLoader.loadClass("org.postgresql.util.PGobject");
               Constructor ct = aPGObjectClass.getConstructor(null);
               try {
                tempInet = ct.newInstance(null);
            } catch (InstantiationException | IllegalAccessException
                    | IllegalArgumentException | InvocationTargetException e2) {
                // TODO Auto-generated catch block
                e2.printStackTrace();
            }
    
               Method setTypeMethod = aPGObjectClass.getMethod("setType", new Class[]{String.class});
               try {
    
                   //Setting postgresql type, inet in this case
    
                setTypeMethod.invoke(tempInet, new Object[]{"inet"});
            } catch (IllegalAccessException | IllegalArgumentException
                    | InvocationTargetException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
    
               Method setValueMethod = aPGObjectClass.getMethod("setValue", new Class[]{String.class});
               try {
                setValueMethod.invoke(tempInet, new Object[]{value.toString()});
            } catch (IllegalAccessException | IllegalArgumentException
                    | InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
           } catch (ClassNotFoundException e) {
    
           } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    
           return tempInet;
       }
    
    @Override
    public Object deepCopy(Object value) throws HibernateException {
        if(value==null)
            return null;
        else{
            PgInet PgInetNew=new PgInet();
            PgInet PgInetOriginal=(PgInet)value;
    
            PgInetNew.setAddress(PgInetOriginal.getAddress());
    
            return PgInetNew;
        }
    }
    
    @Override
    public boolean isMutable() {
        return false;
    }
    
    @Override
    public Serializable disassemble(Object value) throws HibernateException {
         Object  deepCopy=deepCopy(value);
    
          if(!(deepCopy instanceof Serializable))
           return (Serializable)deepCopy;
    
          return null;
    }
    
    @Override
    public Object assemble(Serializable cached, Object owner)
            throws HibernateException {
        return deepCopy(cached);
    }
    
    @Override
    public Object replace(Object original, Object target, Object owner)
            throws HibernateException {
        return deepCopy(original);
    }
    
     }
    

    当我从DB中插入或获取一行时,这种方法对我来说很好