mattis
mattis

Reputation: 211

PGpoint Hibernate (de)serialization exception

In my database I've this table:

CREATE TABLE base_station
(
    MCC INT NOT NULL,
    MNC INT NOT NULL,
    LAC INT NOT NULL,
    CID INT NOT NULL,
    type TEXT NOT NULL,
    geoposition point NOT NULL,
    city TEXT,
    date_created DATE,
    PRIMARY KEY ( CID, MNC, LAC, MCC ),
    FOREIGN KEY ( MNC, LAC, MCC ) REFERENCES location_area ( MNC, LAC, MCC ) ON DELETE CASCADE DEFERRABLE
);

where geoposition is of POINT type. I've read that postgresql POINT should be mapped to PGpoint, but when trying do deserialize data I'm getting this exception:

org.hibernate.type.SerializationException: could not deserialize
    org.hibernate.internal.util.SerializationHelper.doDeserialize(SerializationHelper.java:262)
    org.hibernate.internal.util.SerializationHelper.deserialize(SerializationHelper.java:306)
    org.hibernate.type.descriptor.java.SerializableTypeDescriptor.fromBytes(SerializableTypeDescriptor.java:140)
    org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:121)
    org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:44)
    org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor$2.doExtract(VarbinaryTypeDescriptor.java:67)
    org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:64)
    org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:261)
    org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:257)
    org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:247)
    org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:332)
    org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2912)
    org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1673)
    org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1605)
    org.hibernate.loader.Loader.getRow(Loader.java:1505)
    org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:713)
    org.hibernate.loader.Loader.processResultSet(Loader.java:943)
    org.hibernate.loader.Loader.doQuery(Loader.java:911)
    org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:342)
    org.hibernate.loader.Loader.doList(Loader.java:2526)
    org.hibernate.loader.Loader.doList(Loader.java:2512)
    org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2342)
    org.hibernate.loader.Loader.list(Loader.java:2337)
    org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:495)
    org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:357)
    org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:195)
    org.hibernate.internal.SessionImpl.list(SessionImpl.java:1269)
    org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
    pl.elka.networkwatcher.dao.implemented.HibernateDAOImpl.getList(HibernateDAOImpl.java:49)
    pl.elka.networkwatcher.managers.BaseStationManager.findAll(BaseStationManager.java:25)
    pl.elka.networkwatcher.managers.BaseStationManager$$FastClassByCGLIB$$bbbd79f1.invoke(<generated>)
    org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:698)
    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.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
    pl.elka.networkwatcher.managers.BaseStationManager$$EnhancerByCGLIB$$30a97444.findAll(<generated>)
    pl.elka.networkwatcher.controllers.MainController.stations(MainController.java:61)
    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.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:439)
    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:427)
    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)
    org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 

When I remove geoposition from hibernate mapping, it works fine. Here is a piece of my entity class:

@Column(name = "geoposition", nullable = false)
private PGpoint geoposition;

I'm using PostgreSQL 9.1 without PostGIS. How can i resolve this problem to get hibernate working correctly?

Upvotes: 1

Views: 2118

Answers (3)

krevelen
krevelen

Reputation: 391

Perhaps you still need to set the dialect to PostGIS: hibernate.dialect=org.hibernate.spatial.dialect.postgis.PostgisDialect

Upvotes: 0

TheSteve0
TheSteve0

Reputation: 3526

I assume point you are using is the PostgreSQL point type? If so then it looks like Hibernate doesn't understand this type or it is not defined in the JDBC driver.

I ran into a similar problem when using Hibernate Spatial and I wasn't locating the postgis.jar.

I would start maybe by trying straight JDBC to work with the PostgreSQL point type. If that can work then look to Hibernate.

Upvotes: 2

j.bergmann
j.bergmann

Reputation: 41

One thing you can do is, if you don't need the point type on DB column, you can change that to bytea

e.g.:

@Column(name = "geoposition", columnDefinition = "bytea")
public PGpoint getGeoposition()
{ 
     return this.geoposition; 
}

A better way is to set up an User Type, here you can find a good example: http://learningviacode.blogspot.de/2011/09/creating-hibernate-custom-type-1.html

Here is what I did:

package testapplication;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
import org.postgresql.geometric.PGpoint;


public class PointUserType implements UserType
{

    @Override
    public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner)
        throws HibernateException, SQLException
    {
    assert names.length == 1;
    if (resultSet.wasNull())
    {
        return null;
    }
        final PGpoint point = new PGpoint(resultSet.getObject(names[0]).toString());
        return point;
    }

    @Override
    public void nullSafeSet(PreparedStatement statement, Object value, int index)
        throws HibernateException, SQLException
    {
        statement.setObject(index, value);
    }

    @Override
    public int[] sqlTypes()
    {
        return new int[]
        {
            Types.VARCHAR
        };
    }

    @SuppressWarnings("rawtypes")
    @Override
    public Class returnedClass()
    {
        return PGpoint.class;
    }

    @Override
    public boolean equals(Object o, Object o1) throws HibernateException
    {
        boolean isEqual = false;
        if (o == o1)
        {
                isEqual = true;
        }
        if (o == null || o1 == null)
        {
            isEqual = false;
        }
        else
        {
            isEqual = o.equals(o1);
        }
        return isEqual;
   }

    @Override
    public int hashCode(Object o) throws HibernateException
    {
        return o.hashCode();
    }

    @Override
    public Object deepCopy(Object o) throws HibernateException
    {
        return (Serializable) o;
    }

    @Override
    public boolean isMutable()
    {
        return true;
    }

    @Override
    public Serializable disassemble(Object o) throws HibernateException
    {
        return (Serializable) o;
    }

    @Override
    public Object assemble(Serializable srlzbl, Object o) throws HibernateException
    {
        return srlzbl;
    }

    @Override
    public Object replace(Object o, Object o1, Object o2) throws HibernateException
    {
        return this;
    }

}

Your column definition should look like this:

@Column(name = "geoposition", columnDefinition = "point")
@Type(type = "testapplication.PointUserType")
public PGpoint getGeoposition()
{
    return geoposition;
}

This allows you to save to and read from postgresql point columns. I haven't been testing it all the way, but it should get you started.

Upvotes: 2

Related Questions