我的同事对我坚持代码生成感到遗憾,但我决心证明这个特定的链是可以完成的。下面的示例是从我的项目中简化的(因此未经测试作为输入);我将很快创建一个测试工具。目前使用休眠 4.1.4、休眠空间 1.1.1、hyperjaxb3-ejb-plugin 0.5.6。
我从一个使用 Position 元素的模式开始,该元素的类型是一个简单的字符串扩展:
<xsd:simpleType name="wktPoint">
<xsd:restriction base="xsd:string">
</xsd:restriction>
</xsd:simpleType>
我使用 bindings.xjb 自定义将我的 xmlType wktPoint 映射到使用 jaxb:javaType 的 JTS Point javaType,因为我希望将 JTS Point 字段映射到 postgis 几何列:
<jaxb:javaType name="com.vividsolutions.jts.geom.Point" xmlType="wktPoint" parseMethod="test.Reader.readWKTPoint" printMethod="test.Writer.writeWKTPoint" />
稍后在 bindings.xjb 中,我开始使用 annox:annotation 自定义 Position 元素:
<jaxb:bindings node="xsd:complexType[@name='MyType']//xsd:element[@name='Position']">
<annox:annotate target="getter">
<annox:annotate annox:class="javax.persistence.Basic"/>
<annox:annotate annox:class="javax.persistence.Column" name="POSITION" columnDefinition="GEOMETRY"/>
<annox:annotate annox:class="org.hibernate.annotations.Type" type="org.hibernatespatial.GeometryUserType">
<annox:annotate annox:field="parameters">
<annox:annotate annox:class="org.hibernate.annotations.Parameter" name="dialect" value="postgis"/>
</annox:annotate>
</annox:annotate>
</annox:annotate>
</jaxb:bindings>
但是,这会在 MyType.java 中生成以下 getPosition 方法:
/**
* Gets the value of the position property.
* @return
* possible object is
* {@link String }
*/
@Transient
@Basic
@Column(columnDefinition = "GEOMETRY", name = "POSITION")
@Type(parameters = {
@Parameter(name = "dialect", value = "postgis")
}, type = "org.hibernatespatial.GeometryUserType")
public Point getPosition() {
return position;
}
因此,当我启动我的应用程序并且 jpa/hibernate 开始初始化表时,它会完全跳过 POSITION 列(因为它被标记为@Transient)。
如何防止 @Transient 出现?看来我需要说服 Hyperjaxb 我们将能够将 JTS Point 类型直接写入数据库(这就是所有 @Type 的内容,表明我们希望 hibernatespatial 在读取和写入位置时使用 postgis 方言)。关于如何做到这一点的任何想法?