sle*_*erd 5 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;
...
}
Run Code Online (Sandbox Code Playgroud)
Hibernate(我当前的JPA提供程序)生成数字作为id值,但它们自然只对一种类型唯一,在本例中为Thing.
现在XSD说xsd:id(@XmlID)是一个NCString,它不能是普通数字,所以我在JAXBLongAdapter中为数字加上'_'. - 比如'_1'
现在架构验证器抱怨:
[org.xml.sax.SAXParseException: cvc-id.2: There are multiple occurrences of ID value '_1'.]
Run Code Online (Sandbox Code Playgroud)
如果我理解正确,xsd:ID元素必须具有xml文档中全局唯一的(字符串)值.但这与在数据库中使用ID的常见方式完全相反.
现在我该怎么做?我想到了三件事:
我现在似乎必须更改数据库架构以使用不同的ID. - 但如果ID仍然很短,那将会很好,因为它们出现在URL中.
我的问题:ID发生器是否具有相对快速且全球独一无二的特点?还是有另一种解决方法吗?
编辑:
这种黑客有点工作,使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+"###");
}
}
Run Code Online (Sandbox Code Playgroud)
通过将JAXB Annotation从字段移动到XmlID的专用私有getter/setter.
这正是我一段时间以来所做的事情。
您可以问自己,@XmlID编组时该域对象实际上是什么?
我曾经想过@XmlID并且@XmlIDREF可以解决JAXB中的循环问题。
以下是我使用 JPA 实体和 JAXB 注释所做的事情。
不要放弃simple 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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2279 次 |
| 最近记录: |