如何将org.postgresql.geometric.PGpoint映射到Hibernate类型

时间:2014-08-26 20:46:07

标签: java hibernate postgresql jpa

我正在将我的应用程序从spring jdbc迁移到JPA + Hibernate,而使用的数据库是postgres。我在DB中的一个表有点数据类型,如果我使用spring jdbc,则转换为org.postgresql.geometric.PGpoint。我不知道如何将其映射到Hibernate类型。有人可以告诉我如何将点数据类型映射到休眠类型。

1 个答案:

答案 0 :(得分:1)

首先,我认为Hibernate Spatial支持GEOMETRY数据类型,但如果不支持,您可以随时定义自定义Hibernate类型和自定义Hibernate方言。

在管理包含地理位置的POINT列时,我遇到了类似的问题。

我创建了一个扩展PostgisDialect的{​​{1}}类,以这种方式注册新数据类型

PostgreSQL9Dialect

在您的情况下,您可以将类型注册为" geometry"

然后,您定义了一个实现public PostgisDialect() { registerColumnType(Types.BINARY, "geography"); }

GeometryType

奇怪的是,编写自定义Hibernate Type的过程并不是最有记录的功能之一,因此我将在此处粘贴我编写的用于定义PointType的内容。对于界面中的其他方法,我让他们抛出UserType

UnsupportedOperationException

}

一些快速说明:nullSafeSet和nullSafeGet分别使用BinaryWriter / BinaryParser对象向/从数据库写入和读取值。

一旦定义了所有这些,就是如何为模型类添加注释以便它使用您的自定义类型

public class PointType implements UserType{
private static final Type[] PROPERTY_TYPES = new Type[] { 
    StringType.INSTANCE };
public String[] getPropertyNames() {
     return new String[] {"point"};   }

public Type[] getPropertyTypes() {
    return PROPERTY_TYPES;
}


public Class returnedClass() {
   return Point.class;
}

public boolean equals(Object o, Object o1) throws HibernateException {
    if((o instanceof Point && o1 instanceof Point) == false)
        return false;
    Point p1 = (Point) o;
    Point p2 = (Point) o1;
    boolean equal = ((p1.getX() == p2.getX()) && (p1.getY() == p2.getY()));
    return equal;


}   

public Object nullSafeGet(ResultSet rs, String[] strings, SessionImplementor si, Object o) throws HibernateException, SQLException {
// the method which gets the data from the column and converts it to a Point using       BinaryParser
   BinaryParser bp = new BinaryParser();       
   try{          
      String binaryString = rs.getString(strings[0]);
       return bp.parse(binaryString);
   }
   catch(Exception ex){ return null;}

}

public void nullSafeSet(PreparedStatement ps, Object o, int i, SessionImplementor si) throws HibernateException, SQLException {
    Point p = (Point) o ;
    if(p!=null){
       BinaryWriter bw = new BinaryWriter();
       ps.setObject(i,bw.writeBinary(p));      
    }

public Object deepCopy(Object o) throws HibernateException {
    Point p = (Point) o;        
    Point newPoint = null;
    if(p!=null){
        newPoint = new Point(p.x, p.y);
        newPoint.setSrid(p.getSrid());
    }
    return newPoint;

}

public boolean isMutable() {
    return true;
}


public int[] sqlTypes() {
    return new int[]{Types.BINARY};
}    

最后,但并非最不重要的是,您需要告诉Hibernate使用您的自定义方言。如果您使用Spring来定义会话工厂,则可以通过@Column(name="point") @Type(type="eu.enricorampazzosoluzioni.incidentpredicter.dataCopier.hibernate.types.PointType") private Point point;

进行定义
hibernateProperties