如何将org.postgresql.geometric.PGpoint映射到Hibernate类型 [英] How to map org.postgresql.geometric.PGpoint to Hibernate Type

查看:136
本文介绍了如何将org.postgresql.geometric.PGpoint映射到Hibernate类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

解决方案

首先,我认为 GEOMETRY 数据类型由支持,但如果他们不是,你总是可以定义一个自定义的Hibernate类型和一个自定义的Hibernate方言。



当管理 POINT 包含地理点的列。



我创建了一个扩展 PostgreSQL9Dialect PostgisDialect 类,在这里注册新的数据类型

  public PostgisDialect(){
registerColumnType(Types.BINARY,地理);
}

在这种情况下,您可以将类型注册为geometry



然后,定义一个类,它实现 UserType 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;

$ b $ public boolean equals(Object o,Object o1)throws HibernateException {
if((o instanceof Point&& o1 instanceof Point)== false)
返回false;
Point p1 =(Point)o;
Point p2 =(Point)o1;
boolean equal =((p1.getX()== p2.getX())&&(p1.getY()== p2.getY()));
回报相等;



$ b public Object nullSafeGet(ResultSet rs,String [] strings,SessionImplementor si,Object o)throws HibernateException,SQLException {
//从列中获取数据并使用BinaryParser将其转换为Point的方法
BinaryParser bp = new BinaryParser();
尝试{
String binaryString = rs.getString(strings [0]);
返回bp.parse(binaryString);
}
catch(Exception ex){return null;}


$ b $ public void nullSafeSet(PreparedStatement ps,Object o,int i,SessionImplementor si)抛出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());
}
返回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来定义会话工厂,你可以通过 hibernateProperties

来定义它。

pre $ < property name =hibernateProperties>
<道具>
< prop key =hibernate.dialect> eu.enricorampazzosoluzioni.incidentpredicter.dataCopier.hibernate.dialect.PostgisDialect< / prop>
< /道具>
< / property>


I'm migrating my application from spring jdbc to JPA + Hibernate and the DB used is postgres. One of my table in the DB has point data type which translates to org.postgresql.geometric.PGpoint if i use spring jdbc. I don't how to map this to Hibernate type. Can some one please let me know how do I map the point data type to a hibernate type.

解决方案

First and foremost, I think GEOMETRY data types are supported by Hibernate Spatial, but if they are not, you can always define a custom Hibernate Type and a custom Hibernate Dialect.

I had a similar problem when managing a POINT column which contained geography points.

I created a PostgisDialect class which extended PostgreSQL9Dialect, where you register the new data type in this way

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

in your case, you would register the type as "geometry"

then, you define a GeometryType class which implements UserType

Oddly enough, the process of writing a custom Hibernate Type is not one of the most documented features, so I will paste here what I wrote to define my PointType. For the other methods in the interface, I let them throw 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};
}    

}

some quick notes: nullSafeSet and nullSafeGet writes and reads the values to/from the database, respectively, using the BinaryWriter/BinaryParser objects.

Once you have defined all this, this is how you annotate your model class so that it uses your custom type

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

Last, but not least, you need to tell Hibernate to use your custom dialect. If you use Spring to define your session factory, you can define it via hibernateProperties

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

这篇关于如何将org.postgresql.geometric.PGpoint映射到Hibernate类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆