我有一种情况,我正在使用Hibernate(5.2.16)来映射表,其中一个列值是通过一个数据库函数构建的,该函数接受另外两个属性的值。
对于某些背景,这是一个带有ST_GEOMETRY列的SDE空间表。据我所知,这与Hibernate支持的两种类型的空间API不兼容,但即使它是,我也没有做任何空间操作,所以我真的不需要它们,我只是想要插入和更新几何列。
我绝对无法控制表格的结构,因为它是由另一个使用其他工具(GIS)的团队决定的。
我尝试过的事情:
UserType
。这个问题是我只看到一种方法来获取和设置值为PreparedStatement
,而无法指定实际使用的SQL。
basic-custom-type 使用休眠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必须只包含一个值占位符('?')字符:property [shape]和column [SHAPE]
我查看了Generated
列,但这些列是由数据库生成的值。
mapping-generated
我查看了Formula
列,但这些列用于在Java中计算和使用的值,但未插入或更新。 mapping-column-formula
@Formula(value="sde.st_astext(shape)")
private String shape;
它对某些内容很有用,但我无法插入或更新它。
我希望我错过了一些东西。此时我正在考虑非Hibernate / JPA解决方案。对于原始SQL和JDBC,这会相对容易,但表的其余部分会很烦人,并且与我的其余代码不匹配。我还必须自己进行脏检查。
答案 0 :(得分:1)
您可以使用Hibernate database generated value。它允许您调用数据库函数来生成实体属性。
答案 1 :(得分:1)
这是一个特定于数据库的答案,但是鉴于您的GIS问题域和PostGIS的优势,它可能是相关的(如果您使用PostgreSQL并且您的DBA可以升级)。
PosgreSQL 12引入了generated columns,您可以使用类似于以下内容的方法进行定义:
@Column(columnDefinition = "GEOMETRY GENERATED ALWAYS AS st_transform(st_point(LONGITUDE,LATITUDE, 4326), 3857)) STORED")