如何将org.postgresql.geometric.PGpoint映射到Hibernate类型 [英] How to map org.postgresql.geometric.PGpoint to Hibernate Type
问题描述
我将我的应用程序从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
奇怪的是,编写自定义Hibernate类型的过程并不是最常见的功能之一,因此我将在此处粘贴我写的用于定义我的PointType的内容。对于接口中的其他方法,我让它们抛出 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屋!