Ho implementato un'API REST basata su JPA e JAXB.JPA Long @Id come JAXB @XmlID genera l'errore di convalida XSD
Ho un classi più o meno come questo (molto semplificato):
@Entity
@XmlRootElement
...
public class Thing {
@Id
@GeneratedValue
...
@XmlAttribute
@XmlID
@XmlJavaTypeAdapter(JAXBLongAdapter.class)
private Long id;
...
}
Hibernate (il mio provider JPA corrente) genera numeri come il valore id, ma sono naturalmente unici per un solo tipo, cosa in questo esempio.
Ora XSD dice che xsd: id (@XmlID) è un NCString che non può essere un numero semplice quindi ho anteposto un '_' ai numeri in JAXBLongAdapter. - come '_1'
Ora il validatore schema si lamenta:
[org.xml.sax.SAXParseException: cvc-id.2: There are multiple occurrences of ID value '_1'.]
Se ho capito bene un xsd: element ID deve avere un valore (stringa) che è univoco nel documento XML. Ma questo è molto diverso dal modo comune di usare gli ID nei database.
Cosa faccio adesso? ho pensato tre cose:
- Creare un JAXBLongAdapter per ogni tipo con un prefisso specifico tipo?
- Utilizzare un altro generatore di ID JPA, forse UUID? - Ma quale?
- Interrompere l'utilizzo di @XmlID e @XmlIDREF, che crea ridondanza e problemi generali.
Sembra che ora debba modificare lo schema del database per utilizzare ID diversi. - Ma sarebbe bello se gli ID rimanessero brevi, perché compaiono negli URL.
La mia domanda: esiste un generatore di ID che sia comparabilmente veloce e globalmente unico? O c'è un altro modo per affrontarlo?
EDIT:
Questo mod funziona un pò, lasciando intatto il ID APP.
@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+"###");
}
}
Spostando il JAXB annotazione dal campo alla dedicati getter/setter privati per la XmlID.
Vedere http://stackoverflow.com/questions/9629948/jaxb-what-should-be-returned-from-beforemarshalmarshaller-method –