JPA と JAXB に基づいて REST API を実装しました。
私は大まかに次のようなクラスを持っています(非常に単純化されています):
@Entity
@XmlRootElement
...
public class Thing {
@Id
@GeneratedValue
...
@XmlAttribute
@XmlID
@XmlJavaTypeAdapter(JAXBLongAdapter.class)
private Long id;
...
}
Hibernate (私の現在の JPA プロバイダー) は id 値として数値を生成しますが、それらは当然 1 つの型 (この例では Thing) に対してのみ一意です。
現在、XSD は、xsd:id (@XmlID) は NCString であり、単純な数値にすることはできないため、JAXBLongAdapter の数値の先頭に「_」を追加しました。-「_1」のように
今、スキーマバリデータは不平を言います:
[org.xml.sax.SAXParseException: cvc-id.2: There are multiple occurrences of ID value '_1'.]
これを正しく理解している場合、xsd:ID 要素には、xml ドキュメント内でグローバルに一意の (文字列) 値が必要です。しかし、これはデータベースで ID を使用する一般的な方法とは正反対です。
私は今何をしますか?次の3つのことを考えました。
- タイプ固有のプレフィックスを使用して、タイプごとに JAXBLongAdapter を作成しますか?
- 別の JPA id ジェネレーター、おそらく UUID を使用していますか? - でもどれ?
- @XmlID と @XmlIDREF の使用を停止すると、冗長性と全体的な混乱が生じます。
別の ID を使用するには、データベース スキーマを変更する必要があるようです。- しかし、ID は URL に表示されるため、ID が短いままであるとよいでしょう。
私の質問: 比較的高速でグローバルにユニークな 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+"###");
}
}
JAXB アノテーションをフィールドから XmlID 専用のプライベート ゲッター/セッターに移動する。