java - JPA Long @Id as JAXB @XmlID 生成 XSD 验证错误

标签 java jpa jaxb jpa-2.0

我已经实现了一个基于 JPA 和 JAXB 的 REST API。

我有一个大致像这样的类(非常简化):

@Entity
@XmlRootElement
...
public class Thing {
    @Id
    @GeneratedValue
    ...
    @XmlAttribute
    @XmlID
    @XmlJavaTypeAdapter(JAXBLongAdapter.class)
    private Long id;
    ...
}

Hibernate(我当前的 JPA 提供程序)生成数字作为 id 值,但它们自然只对一种类型是唯一的,在此示例中为 Thing。

现在 XSD 说 xsd:id (@XmlID) 是一个不能是纯数字的 NCString,所以我在 JAXBLongAdapter 中的数字前加了一个“_”。 - 喜欢'_1'

现在模式 validator 提示:

[org.xml.sax.SAXParseException: cvc-id.2: There are multiple occurrences of ID value '_1'.]

如果我理解正确,则 xsd:ID 元素必须具有在 xml 文档中全局唯一的(字符串)值。但这与在数据库中使用 ID 的常见方式截然相反。

我现在该怎么办? 我想到了三件事:

  • 为每个带有特定类型前缀的类型创建一个 JAXBLongAdapter?
  • 使用另一个 JPA id 生成器,也许是 UUID? - 但是哪一个?
  • 停止使用 @XmlID 和 @XmlIDREF,它们会造成冗余和困惑。

看来我现在必须更改数据库架构以使用不同的 ID。 - 但如果 ID 保持简短就好了,因为它们出现在 URL 中。

我的问题:是否有速度相对较快且全局唯一的 ID 生成器? 或者有其他方法可以解决这个问题吗?

编辑:

这种 hack 有点管用,让 JPA ID 完好无损。

@XmlID
@XmlAttribute(name="id")
private String getXmlID(){
    return String.format("%s-%s", this.getClass().getSimpleName(), this.getId().toString());
}

private void setXmlID(String xmlid){
    String prefix = String.format("%s-", this.getClass().getSimpleName());
    if(xmlid.startsWith(prefix)){
        this.id = Long.parseLong(xmlid.substring(prefix.length()));
    }else{
        throw new IllegalArgumentException(xmlid+" does not look like "+prefix+"###");
    }
}

通过将 JAXB 注释从字段移动到 XmlID 的专用私有(private) getter/setter。

最佳答案

这正是我一段时间以来所做的。

您可以问问自己,编码时此域对象的实际 @XmlID 是什么?

我曾经认为@XmlID@XmlIDREF可以解决JAXB中的循环问题。

这是我使用 JPA 实体以及 JAXB 注释所做的事情。

不要放弃简单的JPA @Id。这是 JPA 的核心。

@XmlRootElement
public class Parent {

    @Id
    @XmlAttribute
    private Long id;

    @OneToMany
    @XmlElement(name = "child")
    @XmlElementWrapper
    private Collection<Child> children;
}


@XmlRootElement
public class Child {

    @XmlAttribute
    private Long getParentId() {
        return parent.getId();
    }

    @Id
    @XmlAttribute
    private Long id;

    @ManyToOne
    @XmlTransient // for preventing infinite circular problem
    private Parent parent;
}

关于java - JPA Long @Id as JAXB @XmlID 生成 XSD 验证错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11791735/

相关文章:

java - JPQL 的 INNER JOIN 问题(即使 SQL 请求正在运行)

spring - junit 测试用例事务未提交 - 没有错误

xml - 使用冗余命名空间解析 XML

java - LinkageError JAXB 2.0 -> 2.1 (Tomcat)

java - 从映射填充 Java 对象的方法

java - 可执行 jar 文件未运行

Java swing并发,多个propertychangelistener?

Java + Linux : Working Directory is my home folder

java - 对多数据类型字符串进行排序

google-app-engine - google app engine java datastore是否缓存JPA查询结果?