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