首页 > 解决方案 > 使用 JPA AttributeConverter 将类转换为几何

问题描述

我有一个类(PointAreaModel),它封装了一些地理信息,我想将它用作具有 Hibernate 5.2 空间和具有 postgis 的 postgres 的 JPA 实体中的属性。为了保持在我的代码的其他地方使用的相同逻辑,我想使用 AttributeConverter (PointAreaModelConverter) 来保存类的几何属性。

@Converter(autoApply = true)
public  class PointAreaModelConverter implements AttributeConverter<PointAreaModel, Point> {
    public PointAreaModelConverter() {
    }
    @Override
    public Point convertToDatabaseColumn(PointAreaModel attribute) {
        return (attribute != null) ? (Point)(attribute.getAreaGeometry()) : null;
    }
    @Override
    public PointAreaModel convertToEntityAttribute(Point dbData) {
        return (dbData != null) ? new PointAreaModel(dbData.getX(),dbData.getY()) : null;
    }
}

我的实体有这个字段:

private PointAreaModel targetCenteredPoint;

课程是:

public class PointAreaModel implements AreaModel {

    private static final long serialVersionUID = 1L;
    private static final AreaType areaType = AreaType.POINT;
    
    private LatLonPoint areaDefinition;
    private Geometry areaGeometry;


    /** Constructors */

    public PointAreaModel() {}
    
    public PointAreaModel(double lat, double lon) throws IllegalArgumentException {
        this.areaDefinition = new LatLonPoint(lat, lon);
        this.setAreaGeometry();
    }

    /** */

    /** Getters and setters */
    

    @Override
    public AreaType getAreaType() {
        return areaType;
    }

    @Override
    public LatLonPoint getAreaDefinition() {
        return areaDefinition;
    }

    @Override
    public void setAreaDefinition (Serializable areaDefinition) {
        this.areaDefinition = (LatLonPoint) areaDefinition;
        this.setAreaGeometry();
    }

    @Override
    public Geometry getAreaGeometry() {
        return areaGeometry;
    }

    private void setAreaGeometry () {
        GeometryFactory gf=new GeometryFactory();
        areaGeometry=gf.createPoint(areaDefinition.getLonLatCoordinate());
        areaGeometry.setSRID(4326);
    }
    
}

但它失败并出现错误:原因:org.hibernate.MappingException:没有 JDBC 类型的方言映射:1178270318

如果我在控制台日志中搜索此代码,我还会发现:

*

找不到请求的 Java 类 [it.egeos.cut3g.cskcsgadapter.common.areamodels.PointAreaModel] 的匹配范围 JavaTypeDescriptor;回退到静态注册表 00:08:01.303 DEBUG (RegistryHelper.java:56) 使用缓存的 JavaTypeDescriptor 实例用于 Java 类 [org.locationtech.jts.geom.Point] 00:08:01.304 DEBUG (JdbcTypeJavaClassMappings.java:65) JDBC类 [org.locationtech.jts.geom.Geometry] 未知的类型代码映射;使用自定义代码 [1178270318]

奇怪的是,我可以在我的实体的私有字段上使用 Point 或 Geometry 作为数据类型,而不会出现任何问题。这个问题似乎只与转换器有关。使用转换器时,Hibernate 似乎无法识别 postgis 类型。显然我已经设置了正确的方言(Postgis),因为它在任何地方都能正常工作,但在转换器中。我也尝试将 Point 更改为 Geometry 并获得相同的结果。如果我将 Point 更改为 String 一切正常。

最后一次尝试是在我的实体中添加明确的列定义:

@Column(columnDefinition = "Geometry")

在这种情况下,应用程序启动时,模式已正确生成,但尝试插入时,会出现错误消息:

*

00:45:09.387 DEBUG (AttributeConverterSqlTypeDescriptorAdapter.java:87) 绑定转换值:it.egeos.cut3g.cskcsgadapter.common.areamodels.PointAreaModel@17​​d606c9 -> POINT (1 2) 00:45:09.388 TRACE (BasicBinder.java :64) 绑定参数 [5] 作为 [VARBINARY] - [POINT (1 2)] 00:45:09.391 INFO (AbstractBatchImpl.java:208) HHH000010:在批处理发布时它仍然包含 JDBC 语句 00:45:09.394 INFO (ConditionEvaluationReportLoggingListener.java:136) 启动 ApplicationContext 时出错。要显示条件报告,请在启用“调试”的情况下重新运行您的应用程序。00:45:09.413 错误 (SpringApplication.java:856) 应用程序运行失败 java.lang.IllegalStateException: 无法在 org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:807) 在 org.springframework.boot 执行 CommandLineRunner。SpringApplication.callRunners(SpringApplication.java:788) at org.springframework.boot.SpringApplication.run(SpringApplication.java:333) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1309) at org.springframework.boot .SpringApplication.run(SpringApplication.java:1298) at it.egeos.cut3g.cskcsgadapter.feasibility.Application.main(Application.java:33) 原因:org.springframework.orm.jpa.JpaSystemException:未知的展开转换请求: org.locationtech.jts.geom.Geometry 到 [B; 嵌套异常是 org.hibernate.HibernateException: Unwrap conversion requested: org.locationtech.jts.geom.Geometry to [B at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:331) at org. springframework.orm.jpa.vendor.HibernateJpaDialect。

任何人都可以帮助我寻找解决方案吗?提前致谢。

更新 1:我找到了这个参考https://gitter.im/hibernate/hibernate-orm?at=5ab11305e4d1c636041f1251 如果您搜索“方言”,您会看到类似的问题。答案似乎是转换器不支持几何类型。也许 Hibernate 6 可以实现。有人还有其他建议吗?

标签: javahibernatepostgisconverters

解决方案


推荐阅读