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

标签 java hibernate postgresql jpa

我正在将我的应用程序从 spring jdbc 迁移到 JPA + Hibernate,并且使用的数据库是 postgres。如果我使用 spring jdbc,我在数据库中的一个表具有转换为 org.postgresql.geometric.PGpoint 的点数据类型。我不知道如何将其映射到 Hibernate 类型。谁能告诉我如何将点数据类型映射到 hibernate 类型。

最佳答案

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

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

我创建了一个 PostgisDialect 类,它扩展了 PostgreSQL9Dialect,您可以在其中以这种方式注册新的数据类型

public PostgisDialect() {
    registerColumnType(Types.BINARY, "geography");        
}

在您的情况下,您会将类型注册为“几何”

然后,您定义一个 GeometryType 类来实现 UserType

奇怪的是,编写自定义 Hibernate Type 的过程并不是记录最多的功能之一,因此我将在此处粘贴我为定义 PointType 而编写的内容。对于接口(interface)中的其他方法,我让它们抛出 UnsupportedOperationException

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};
}    

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

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

@Column(name="point")
@Type(type="eu.enricorampazzosoluzioni.incidentpredicter.dataCopier.hibernate.types.PointType")
private Point point;

最后但同样重要的是,您需要告诉 Hibernate 使用您的自定义方言。如果你使用 Spring 来定义你的 session 工厂,你可以通过 hibernateProperties

来定义它
<property name="hibernateProperties">
     <props>           
         <prop key="hibernate.dialect">eu.enricorampazzosoluzioni.incidentpredicter.dataCopier.hibernate.dialect.PostgisDialect</prop>            
     </props>
  </property>

关于java - 如何将 org.postgresql.geometric.PGpoint 映射到 Hibernate 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25514859/

相关文章:

java - 使用 Try Catch InputMismatchException 进行多个用户输入

java - 使用 Spring 框架在整个应用程序中保留一个对象

java - Hibernate 模式验证失败,MySQL CHAR 映射到 String

python - 使用 psycopg2 执行 SQL 查询

java - 将Java连接到MySQL数据库

java - JPA 如何获取 Criteria API 中使用的参数标记的数量?

java - 如何在hibernate中使用@IndexColumn注释对列表进行排序?

postgresql - 双向复制设计 : best way to script and execute unmatched row on Source DB to multiple subscriber DBs, 顺序还是并发?

Postgresql 转义美元符号

java - 撤销ActiveMQ消息