sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur man mappar org.postgresql.geometric.PGpoint till Hibernate Type

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>



  1. Mitt webbhotell säger att det är något fel med PHP-kod

  2. Vilka är skillnaderna mellan ett klustrat och ett icke-klustrat index?

  3. Tvetydigt kolumnfel i Laravel 4

  4. Varför kräver Oracle ett alias för kolumner i en vy när man refererar ett objekt?