Pertama dan terpenting, saya pikir GEOMETRY
tipe data didukung oleh Hibernate Spatial
, tetapi jika tidak, Anda selalu dapat menentukan Jenis Hibernasi khusus dan Dialek Hibernasi khusus.
Saya memiliki masalah serupa saat mengelola POINT
kolom yang berisi titik-titik geografi.
Saya membuat PostgisDialect
kelas yang memperluas PostgreSQL9Dialect
, tempat Anda mendaftarkan tipe data baru dengan cara ini
public PostgisDialect() {
registerColumnType(Types.BINARY, "geography");
}
dalam kasus Anda, Anda akan mendaftarkan jenisnya sebagai "geometri"
lalu, Anda mendefinisikan GeometryType
kelas yang mengimplementasikan UserType
Anehnya, proses penulisan Tipe Hibernate kustom bukanlah salah satu fitur yang paling didokumentasikan, jadi saya akan menempelkan di sini apa yang saya tulis untuk mendefinisikan PointType saya. Untuk metode lain di antarmuka, saya membiarkan mereka membuang 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};
}
}
beberapa catatan singkat:nullSafeSet dan nullSafeGet masing-masing menulis dan membaca nilai ke/dari database, menggunakan objek BinaryWriter/BinaryParser.
Setelah Anda mendefinisikan semua ini, ini adalah cara Anda memberi anotasi pada kelas model Anda sehingga menggunakan tipe kustom Anda
@Column(name="point")
@Type(type="eu.enricorampazzosoluzioni.incidentpredicter.dataCopier.hibernate.types.PointType")
private Point point;
Terakhir, namun tidak kalah pentingnya, Anda perlu memberi tahu Hibernate untuk menggunakan dialek khusus Anda. Jika Anda menggunakan Spring untuk mendefinisikan pabrik sesi Anda, Anda dapat mendefinisikannya melalui hibernateProperties
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">eu.enricorampazzosoluzioni.incidentpredicter.dataCopier.hibernate.dialect.PostgisDialect</prop>
</props>
</property>