alex
alex

Reputation: 3442

Hibernate spatial with postgis and Spring: can't get back spatial data

I have this problem: I can write to a Postgis table with a geography type column and the data is entered correctly. When I try to get it back, I get a java.lang.IllegalArgumentException: Can't convert object of type org.postgresql.util.PGobject

I'm using Hibernate Spatial 4.0M1, Postgis 2.0.2, Postgresql 9.1.7 and Spring 3.2, Postgis-jdbc 2.0.2 and I tried also 1.5.2 and Postgresql-jdbc 9.1-901.

This is the relevant part of my class

public class Poi {
@Id
@GeneratedValue(generator="t_pois_poisid_seq")
private long poisid;
@Column(name="name")
private String name;
@Column(name="userid")
private int owner;
//@Column(columnDefinition = "Geometry", name="location")
@Type(type="org.hibernate.spatial.GeometryType")
private Point location;


public Poi(){}

public Poi(String name, int owner, String wktPoint){
    this.name = name;
    this.owner = owner;
    WKTReader fromText = new WKTReader();
    Geometry geom = null;
    try{
        geom = fromText.read(wktPoint);
    }catch(ParseException e){
        throw new RuntimeException("Not a WKT string:" + wktPoint);
    }
    if (!geom.getGeometryType().equals("Point")) {
        throw new RuntimeException("Geometry must be a point. Got a " +  geom.getGeometryType());
    }
    //geom.setSRID(4326);
    this.location = (Point) geom;

}

}

And this is the error I get

java.lang.IllegalArgumentException: Can't convert object of type org.postgresql.util.PGobject org.hibernate.spatial.dialect.postgis.PGGeometryValueExtractor.toJTS(PGGeometryValueExtractor.java:99) org.hibernate.spatial.dialect.AbstractJTSGeometryValueExtractor.extract(AbstractJTSGeometryValueExtractor.java:42) org.hibernate.spatial.dialect.AbstractJTSGeometryValueExtractor.extract(AbstractJTSGeometryValueExtractor.java:37) org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:269) org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:265) org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:238) org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:357) org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2807) org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1545) org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1477) org.hibernate.loader.Loader.getRow(Loader.java:1377) org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:644) org.hibernate.loader.Loader.doQuery(Loader.java:854) org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:293) org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:263) org.hibernate.loader.Loader.loadEntity(Loader.java:1977) org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:82) org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:72) org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3821) org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:458) org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:427) org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:204) org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:260) org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:148) org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1075) org.hibernate.internal.SessionImpl.access$2000(SessionImpl.java:175) org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(SessionImpl.java:2421) org.hibernate.internal.SessionImpl.get(SessionImpl.java:971) com.prismio.pois.api.repository.HibernatePoiRepository.findOne(HibernatePoiRepository.java:30) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(Method.java:601) org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317) org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110) org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) $Proxy24.findOne(Unknown Source) com.prismio.pois.api.controller.PoiController.getUser(PoiController.java:40) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(Method.java:601) org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219) org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:746) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:687) org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:915) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:811) javax.servlet.http.HttpServlet.service(HttpServlet.java:621) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:796) javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

Upvotes: 1

Views: 3670

Answers (1)

alex
alex

Reputation: 3442

If anyone is interested: the problem is that PostGIS returns a PGObject from a column type Geography and not PGGeometry, so the cast to PGgeometry is not possible. The solution I found using jdbcTemplate (and not Hibernate) is to cast the field from the resultset to PGObject and then create a PGGeometry like this:

PGgeometry geo = new PGgeometry(myPGObject.getValue());

Doing this, geo.getValue() returns a string in the form SRID=4326;POINT(40.70686417491799 -74.01572942733765) which is what I wanted. I could do the query using ST_AsText but it loses precision. I don't know Hibernate well enough to propose a solution to this, but this is enough for my use case.

Upvotes: 5

Related Questions