【问题标题】:PGpoint Hibernate (de)serialization exceptionPGpoint Hibernate(反)序列化异常
【发布时间】:2013-11-14 07:04:34
【问题描述】:

在我的数据库中,我有这张表:

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
);

地理位置是 POINT 类型。我读过 postgresql POINT 应该映射到 PGpoint,但是在尝试反序列化数据时,我得到了这个异常:

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) 

当我从休眠映射中删除地理位置时,它工作正常。 这是我的实体类的一部分:

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

我正在使用没有 PostGIS 的 PostgreSQL 9.1。 如何解决此问题以使休眠正常工作?

【问题讨论】:

  • 您没有使用 PostGIS 是否有特定原因?
  • 我的项目中不需要 PostGIS。唯一需要的是具有单一属性的地理位置而不是两个:纬度和经度。但似乎不可能这样做..
  • 我也遇到了这个问题。我正在使用休眠空间。

标签: java hibernate postgresql orm hibernate-mapping


【解决方案1】:

也许你还需要将方言设置为 PostGIS:hibernate.dialect=org.hibernate.spatial.dialect.postgis.PostgisDialect

【讨论】:

    【解决方案2】:

    我假设您使用的是 PostgreSQL point 类型?如果是这样,那么看起来 Hibernate 不理解这种类型,或者它没有在 JDBC 驱动程序中定义。

    我在使用 Hibernate Spatial 时遇到了类似的问题,但我没有找到 postgis.jar。

    我可能会首先尝试直接使用 JDBC 来处理 PostgreSQL point 类型。如果这可以工作,那么看看 Hibernate。

    【讨论】:

      【解决方案3】:

      您可以做的一件事是,如果您不需要 DB 列上的点类型,您可以将其更改为 bytea

      例如:

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

      一个更好的方法是设置一个用户类型,在这里你可以找到一个很好的例子: http://learningviacode.blogspot.de/2011/09/creating-hibernate-custom-type-1.html

      这是我所做的:

      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;
          }
      
      }
      

      您的列定义应如下所示:

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

      这允许您保存到 postgresql 点列并从中读取。我没有一直测试它,但它应该能让你开始。

      【讨论】:

        猜你喜欢
        • 2017-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多