Först och främst tänker jag på GEOMETRY
datatyper stöds av Hibernate Spatial
, men om de inte är det, kan du alltid definiera en anpassad Hibernate Type och en anpassad Hibernate Dialect.
Jag hade ett liknande problem när jag hanterade en POINT
kolumn som innehöll geografipunkter.
Jag skapade en PostgisDialect
klass som utökade PostgreSQL9Dialect
, där du registrerar den nya datatypen på detta sätt
public PostgisDialect() {
registerColumnType(Types.BINARY, "geography");
}
i ditt fall skulle du registrera typen som "geometri"
sedan definierar du en GeometryType
klass som implementerar UserType
Konstigt nog är processen att skriva en anpassad Hibernate Type inte en av de mest dokumenterade funktionerna, så jag kommer att klistra in här vad jag skrev för att definiera min PointType. För de andra metoderna i gränssnittet låter jag dem kasta 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};
}
}
några snabba anteckningar:nullSafeSet och nullSafeGet skriver och läser värdena till/från databasen, med hjälp av BinaryWriter/BinaryParser-objekten.
När du har definierat allt detta är det så här du kommenterar din modellklass så att den använder din anpassade typ
@Column(name="point")
@Type(type="eu.enricorampazzosoluzioni.incidentpredicter.dataCopier.hibernate.types.PointType")
private Point point;
Sist men inte minst måste du berätta för Hibernate att använda din anpassade dialekt. Om du använder Spring för att definiera din sessionsfabrik kan du definiera den via hibernateProperties
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">eu.enricorampazzosoluzioni.incidentpredicter.dataCopier.hibernate.dialect.PostgisDialect</prop>
</props>
</property>