Posso inserire annotazioni per più processori in una classe Java?
-
06-07-2019 - |
Domanda
Non sono davvero sicuro di come funzionano effettivamente le annotazioni. Sto usando JAXB e JPA (con eclipselink) sulle stesse classi, i. e. Ottengo definizioni di classe come questa:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Channel")
@Entity
public class Channel extends NamedEntity {
@XmlAttribute
@XmlSchemaType(name = "anyURI")
@Column(name="url")
protected String url;
@XmlAttribute
@Column
protected String coDirection;
// etc...
}
Ora sto riscontrando strani errori (ad esempio " com.econemon.suite.common.models.Channel@115c974 non è un tipo di entità noto " che di solito significherebbe che la classe non è nel mio persistence.xml) e mi chiedo se le annotazioni interferiranno l'una con l'altra?
Soluzione
Un'annotazione non può interferire con un'altra annotazione, esp. non se provengono da pacchetti diversi e hanno nomi diversi. Ogni framework (JAXB e Hibernate) ha le proprie annotazioni. Ogni quadro introspetto contiene solo le proprie annotazioni. Sono molto sicuro che questo non sia il problema qui.
controlla la tua entità per avere questo:
a) nessun costruttore di argomenti (il costruttore predefinito va bene, ma se si hanno solo costruttori con argomenti, è necessario fornire un costruttore senza argomenti a JPA, questo può essere protetto o pacchetto visibile ....)
b) un'annotazione @Id su un campo o getter (usiamo sempre annotazioni basate su campo, altrimenti non mescoliamo mai l'annotazione getter JPA con l'annotazione di campo in un tipo!)
c) il tipo è nell'unità di persistenza e viene utilizzata l'unità di persistenza
d) il tipo ha una @Entity Annotation
se usi l'ereditarietà (estende NamedEntity), devi fornire a JPA più informazioni su come mappare ciò. Inizialmente prova a rimuovere le cose estese di NamedEntity. E poi guarda un buon tutorial JPA che spiega le varianti di eredità.
Altri suggerimenti
No, non lo fanno.
Ho rimosso tutte le altre annotazioni, ho tagliato l'eredità e ho finito con una classe molto semplice. Il problema è rimasto.
Una cosa che non è stata menzionata nel mio post (perché pensavo non fosse rilevante) era che sto eseguendo questo all'interno di un contenitore OSGi (Felix se questo è importante). Ora, un tale contenitore protegge diversi "pacchetti". l'uno dall'altro, in modo che non possano vedersi le rispettive classi fino a quando "l'esportazione" specifica pacchetti.
Le classi annotate si trovavano in un bundle diverso dal mio persistence.xml e supponevo che potevo semplicemente importare le classi annotate da un altro bundle e fare l'init di persistenza altrove. Si scopre che non posso, anche se non ho davvero capito perché.
Quindi, se stai usando JPA insieme ai bundle OSGi, devi assicurarti che:
- Classi annotate e persistence.xml sono insieme nello stesso bundle
- questo bundle esporta il pacchetto contenente le classi annotate
- le unità di persistenza sono elencate nel file manifest del bundle
È quindi possibile eseguire le operazioni di persistenza effettiva (come chiamare EntityManager.persist) in diversi bundle.
Come nota a margine, ho errori simili allo stesso modo quando si tenta di utilizzare le annotazioni JAXB tra i bundle. Sembra che JAXBContext e / o ObjectFactory debbano essere istanziati nello stesso bundle che contiene le classi annotate. Non riuscivo davvero a inchiodarlo, ma mettere le cose nello stesso pacchetto mi ha aiutato.
Sarebbe bello se qualcuno con una comprensione più profonda di OSGi, caricamento di classe e annotazioni potesse commentare cosa potrebbe accadere qui.
Aggiorna : l'esportazione / importazione dei pacchetti di annotazioni appropriati potrebbe consentire di avere persistence.xml e classi annotate in diversi bundle, vedere qui . Non ho ancora testato.