Hibernate/JPA 属性 数据库函数与其他列的映射结果
Hibernate/JPA property mapping result of database function with other columns
我有一种情况,我正在使用 Hibernate (5.2.16) 来映射一个 table 并且其中一个列值是通过一个数据库函数构造的,该函数采用其他两个属性的值。
对于某些背景,这是具有 ST_GEOMETRY 列的 SDE 空间 table。据我所知,这与 Hibernate 支持的两种类型的空间 API 不兼容,但即使是,我也没有进行任何空间操作,所以我真的不需要它们,我只是想要插入和更新几何列。
我完全无法控制 table 的结构,因为它是由另一个小组使用另一个工具 (GIS) 决定的。
我尝试过的事情:
- 使用休眠
UserType
。这个问题是我只看到一种使用 PreparedStatement
获取和设置值的方法,而无法指示实际使用的 SQL。
basic-custom-type
使用 Hibernate ColumnTransformer
。这使我可以直接控制所使用的 SQL,但我无法使用 SQL 中的其他两个属性的值。
mapping-column-read-and-write
@Column(name="LATITUDE")
private BigDecimal latitude;
@Column(name="LONGITUDE")
private BigDecimal longitude;
@ColumnTransformer(
read="sde.st_astext(shape)",
write="sde.st_transform(sde.st_point(LONGITUDE,LATITUDE, 4326), 3857)"
)
@Generated(value=GenerationTime.ALWAYS)
@Column(name="SHAPE")
private String shape;
我得到:
org.hibernate.AnnotationException: @WriteExpression must contain exactly one value placeholder ('?') character: property [shape] and column [SHAPE]
我看过 Generated
列,但那些是数据库生成的值。
mapping-generated
我查看了 Formula
列,但这些是针对在 Java 中计算和使用的值,但未插入或更新。 mapping-column-formula
@Formula(value="sde.st_astext(shape)")
private String shape;
它对某些事情很有用,但我无法插入或更新它。
我希望我错过了什么。此时我正在考虑 non-Hibernate/JPA 解决方案。这对于原始 SQL 和 JDBC 会相对容易,但是 table 的其余部分会很烦人并且与我的代码的其余部分不匹配。我还必须做我自己的肮脏检查和东西。
您可以使用 Hibernate database generated value。它允许您调用数据库函数来生成实体属性。
这是一个特定于数据库的答案,但鉴于您的 GIS 问题域和 PostGIS 的主导地位,它可能是相关的(如果您使用 PostgreSQL 并且您的 DBA 可以升级)。
PosgreSQL 12 引入了 generated columns,您可以使用类似于以下的内容来定义它:
@Column(columnDefinition = "GEOMETRY GENERATED ALWAYS AS st_transform(st_point(LONGITUDE,LATITUDE, 4326), 3857)) STORED")
我有一种情况,我正在使用 Hibernate (5.2.16) 来映射一个 table 并且其中一个列值是通过一个数据库函数构造的,该函数采用其他两个属性的值。
对于某些背景,这是具有 ST_GEOMETRY 列的 SDE 空间 table。据我所知,这与 Hibernate 支持的两种类型的空间 API 不兼容,但即使是,我也没有进行任何空间操作,所以我真的不需要它们,我只是想要插入和更新几何列。
我完全无法控制 table 的结构,因为它是由另一个小组使用另一个工具 (GIS) 决定的。
我尝试过的事情:
- 使用休眠
UserType
。这个问题是我只看到一种使用PreparedStatement
获取和设置值的方法,而无法指示实际使用的 SQL。 basic-custom-type 使用 Hibernate
ColumnTransformer
。这使我可以直接控制所使用的 SQL,但我无法使用 SQL 中的其他两个属性的值。 mapping-column-read-and-write@Column(name="LATITUDE") private BigDecimal latitude; @Column(name="LONGITUDE") private BigDecimal longitude; @ColumnTransformer( read="sde.st_astext(shape)", write="sde.st_transform(sde.st_point(LONGITUDE,LATITUDE, 4326), 3857)" ) @Generated(value=GenerationTime.ALWAYS) @Column(name="SHAPE") private String shape;
我得到:
org.hibernate.AnnotationException: @WriteExpression must contain exactly one value placeholder ('?') character: property [shape] and column [SHAPE]
我看过
Generated
列,但那些是数据库生成的值。 mapping-generated我查看了
Formula
列,但这些是针对在 Java 中计算和使用的值,但未插入或更新。 mapping-column-formula@Formula(value="sde.st_astext(shape)") private String shape;
它对某些事情很有用,但我无法插入或更新它。
我希望我错过了什么。此时我正在考虑 non-Hibernate/JPA 解决方案。这对于原始 SQL 和 JDBC 会相对容易,但是 table 的其余部分会很烦人并且与我的代码的其余部分不匹配。我还必须做我自己的肮脏检查和东西。
您可以使用 Hibernate database generated value。它允许您调用数据库函数来生成实体属性。
这是一个特定于数据库的答案,但鉴于您的 GIS 问题域和 PostGIS 的主导地位,它可能是相关的(如果您使用 PostgreSQL 并且您的 DBA 可以升级)。
PosgreSQL 12 引入了 generated columns,您可以使用类似于以下的内容来定义它:
@Column(columnDefinition = "GEOMETRY GENERATED ALWAYS AS st_transform(st_point(LONGITUDE,LATITUDE, 4326), 3857)) STORED")