2009-06-22 10 views
11

Non mi piace il requisito di avere almeno un costruttore vuoto e setter pubblici su entità JPA. Mentre capisco il problema sul lato EntityManager, questo invalida gli invarianti di classe.Costruttori e setter vuoti su JPA Entites

Qualcuno ha una soluzione per questo (modello di progettazione o livello di idioma)?

Grazie!

Igor

risposta

1

Con DataNucleus non devi aggiungere un costruttore di default se non si vuole; sarà aggiunto automaticamente dall'aumento del bytecode. Inoltre è possibile mantenere i campi anziché le proprietà, quindi non è necessario per i setter pubblici.

--Andy (DataNucleus)

0

Sì, persistono i campi invece di proprietà, ma sul non volere un costruttore di default si è in genere (a meno che il codice di byte potenziatore fa qualche trucco) non hai intenzione di allontanati da esso.

Devi consentire all'implementazione di jpa di istanziare la classe, quindi è obbligatorio un costruttore di public public.

+0

può anche essere protetto, invece di pubblico –

17

Con JPA, è richiesto il costruttore predefinito, tuttavia non è necessario utilizzare setter. È possibile scegliere una strategia di accesso alla proprietà (campo o metodo) in base a dove si posizionano le annotazioni.

Il seguente codice utilizzare l'accesso campo diretto e funzionerà come una parte di un'entità senza un setter:

@Column(name = DESCRIPTION) 
private String description; 

public String getDescription() { return description; } 

Versus accesso metodo con un setter:

private String description; 

@Column(name = DESCRIPTION) 
public void setDescription(String description) { 
    this.description = description; 
} 

public String getDescription() { return description; } 
2

Basta rendere il vostro costruttore protetto o privato, in modo da preservare gli invarianti di classe!

 
public class Person { 
private String firstName; 
private String lastName; 

public Person(String firstName, String lastName) { 
    setFirstName(firstName); 
    setLastName(lastName); 
} 

// private no-arg constructor for hibernate. 
private Person() { 

} 

public String getFirstName() { 
    return firstName; 
} 
public String getLastName() { 
    return lastName; 
} 

// private setters for hibernate 
private void setFirstName(String nme) { 
    firstName = nme; 
} 
private void setLastName(String nme) { 
    lastName = nme; 
} 
} 

vedere http://www.javalobby.org/java/forums/m91937279.html per dettagli.

3

OpenJPA può aggiungere un no-arg ctor come parte del miglioramento delle entità.

Solo così siamo chiari, il requisito è obbligatorio nelle specifiche JPA. La risposta precedente dice che è possibile rendere privato il no-arg ctor, ma non è compatibile con le specifiche (vedo che il collegamento punta a una pagina specifica di Hibernate). La specifica afferma che un'entità deve avere un croup no-arg pubblico o protetto.

-Rick

6

In realtà si dovrebbe avere sia un costruttore senza argomenti e metodi getter e setter. I requisiti sono indicati nella sezione 2.1 di spec.

Il requisito costruttore no-arg si trova a pagina 17 nella mia copia:

classe

L'entità deve avere un costruttore no-arg. La classe di entità può avere anche altri costruttori. Il costruttore no-arg deve essere pubblico o protetto .

pagina 18 ha la necessità di metodi di accesso:

Lo stato persistente di un'entità è rappresentata da variabili di istanza, che possono corrispondere a java- fagioli proprietà. Una variabile di istanza può accessibile direttamente solo da i metodi dell'entità dall'istanza dell'entità stessa. Le variabili dell'istanza non devono essere accessibili dai client dell'entità. Lo stato di l'entità è disponibile per i client solo tramite i metodi di accesso dell'entità (metodi getter/setter) o altri metodi commerciali. Le variabili dell'istanza devono essere private, protette, o visibilità del pacchetto.

L'accesso Campo/Proprietà indica come il provider JPA interagisce con l'entità, non come l'applicazione client interagisce con esso. Il client dovrebbe sempre usare i metodi get e set.

Alcuni provider JPA sono più indulgenti in questi requisiti e si può essere in grado di rendere privato il costruttore (come suggerito sopra) con un fornitore specifico. L'applicazione potrebbe non essere portabile, quindi potresti essere sorpreso se effettui la migrazione in futuro.

Quindi non consiglierei di omettere completamente i metodi. Per risolvere il problema, contrassegno il public no-arg ctor come deprecato (metti qualcosa in javadoc sul fatto che sia usato solo dal provider JPA). I metodi impostati possono contenere la logica che si desidera mantenere invarianti.

Non è l'ideale ma dovrebbe impedire l'utilizzo errato del ctor errato (presumo che tu abbia un ctor che imposta gli invarianti).

+2

Nella seconda citazione si dichiara solo che le altre classi nell'applicazione dell'utente non devono accedere direttamente ai campi dell'entità. Non impone l'esistenza di accessori per il provider JPA. Infatti, la frase successiva è "Lo stato persistente di un'entità è accessibile dal runtime del provider di persistenza tramite gli accessor di proprietà in stile JavaBeans (" accesso alla proprietà ") o tramite variabili di istanza (" accesso al campo ")." Questo mi sembra abbastanza chiaro che non hai bisogno di accessor se stai usando l'accesso al campo, consentendo così di avere variabili di sola lettura. – Pace