java - 使用 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@17d606c9 -> 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 可以实现。有人还有其他建议吗?
解决方案
推荐阅读
- android - Facebook 竞价与 Android 中的 MAX 集成
- python - Python多线程事件监听器
- python-3.x - 如何使用 matplotlib 显示颜色图
- apache-flink - 如何从 flink 作业中查找 db 数据
- node.js - 从 docker 容器中连接到 localhost postgres 数据库
- python - 如何从数据库中读取坐标并使用 django 在地图上映射指针
- javascript - 通过其父类使用 JavaScript 获取子输入的值
- postgresql - 你能描述一下这个FlameGraph(Postgres,RHEL7)为什么CPU等待和阻塞进程吗
- optaplanner - OptaPlanner 是否支持获取计算进度?
- angular - 在使用 ng 命令在谷歌驱动器中使用 angular cli 创建 angular 项目时