sql >> データベース >  >> RDS >> PostgreSQL

Hibernate + PostgreSQL +ネットワークアドレスタイプ(inet、cdir)

    私はあなたのような問題を解決するだけです。この問題に関する情報はほとんどありません。 @ 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からのデータを処理するための構成、およびSeriarizableを取得する必要があります。

    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から行を挿入または取得するときに、うまく機能します。



    1. 前月または前年度の欠落データを累積的に追加する

    2. デフォルトとしてマークされた1つのレコードのみの制約

    3. SQLServerの緊急モードからデータベースを回復する

    4. Galera Cluster Cloudオファリングの比較:パート1 Amazon AWS