costruttore esplicito utilizzando Lombok?
Domanda
Sto riscrivendo un codice disordinato che gestisce un database, e ho visto che il programmatore originale creato una classe mappata al database in questo modo:
(ho rimosso il codice inutile che non ha scopo in questa domanda)
@Entity
@Data
@EqualsAndHashCode(callSuper = false, of = { "accessionCode", "header", "date" })
@SuppressWarnings("PMD.UnusedPrivateField")
public class PDBEntry implements Serializable {
@Id
@NaturalId
@NotEmpty
@Length(max = 4)
private String accessionCode;
@NaturalId
@NotEmpty
private Date date;
@NaturalId
// We allow for the header to be 'null'
private String header;
private Boolean isValidDssp;
@Temporal(TemporalType.TIMESTAMP)
private Date lastUpdated = new Date(System.currentTimeMillis());
protected PDBEntry(){}
public PDBEntry(String accessionCode, String header, Date date){
this.accessionCode = accessionCode;
this.header = header;
this.date = date;
}
}
Sono ancora un principiante in Hibernate e l'utilizzo di Lombok, ma non sarebbe questo fare la stessa cosa e non mi Lombok creare automaticamente il costruttore necessario per voi?
@Entity
@Data
@SuppressWarnings("PMD.UnusedPrivateField")
public class PDBEntry implements Serializable {
@Id
@NaturalId
@NotEmpty
@NonNull
@Length(max = 4)
private String accessionCode;
@NaturalId
@NotEmpty
@NonNull
private Date date;
@NaturalId
// We allow for the header to be 'null'
private String header;
private Boolean isValidDssp;
@Temporal(TemporalType.TIMESTAMP)
private Date lastUpdated = new Date(System.currentTimeMillis());
}
Inoltre, il programmatore originale di questo codice dice che consente per l'intestazione di essere 'nulla', eppure esplicitamente creato un costruttore che ha bisogno di un valore per l'intestazione. Mi sto perdendo qualcosa o si tratta di un po 'contraddittorio?
Soluzione
Date un'occhiata al @NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor
.
Il comportamento costruttore @Data
è come @RequiredArgsConstructor
:
@RequiredArgsConstructor genera un costruttore con 1 parametri per ciascun campo che richiede una gestione speciale. Tutti i campi finali ottengono un parametro, come così come tutti i campi che sono contrassegnati come @NonNull che non sono inizializzati in cui sono dichiarate.
Dato che nessuno dei vostri campi sono o final
o @NonNull
, questo si tradurrà in un costruttore senza argomenti. Tuttavia, questo non è il modo più espressivo per raggiungere questo comportamento.
Ciò che probabilmente si vorrà in questo caso è un @NoArgsConstructor
(eventualmente associato ad un @AllArgsConstructor
), di comunicare chiaramente il comportamento previsto, come è indicato anche nella documentazione:
Alcuni costrutti di Java, come ad esempio Hibernate e il fornitore di servizi Interfaccia richiedere un no-args costruttore. Questa annotazione è utile soprattutto in combinazione con @Data o uno degli altri costruttore annotazioni di generazione.
Altri suggerimenti
Questo bit è contraddittorio Hai ragione. Io non ho usato Lombok prima, ma con Hibernate se si vuole essere in grado di creare un fagiolo e persistere è necessario il costruttore di default, come indicato sopra, per quanto ero consapevole. Esso utilizza Constructor.newInstance () per istanziare nuovi oggetti.
Ecco po 'di documentazione di sospensione che va più nel dettaglio.
Se si utilizza @Data con un campo @NonNull e vuole ancora un noargs costruttore, si potrebbe desiderare di provare ad aggiungere tutti e 3 insieme annotazione
@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor
A quanto pare un vecchio IntelliJ bug che ho fatto replica in Eclipse Keplero e Lombok v0.11.4
@NoArgsConstructor,
@RequiredArgsConstructor,
@AllArgsConstructor
Genera costruttori che non prendono argomenti, un argomento per ogni campo finale / non nullo, o un argomento per ogni campo. Leggi questo Lombok-progetto
@Data
@RequiredArgsConstructor /*Duplicate method Someclass() in type Someclass*/
@NoArgsConstructor(access=AccessLevel.PRIVATE, force=true) /*Duplicate method Someclass() in type Someclass*/
@Entity
public class Someclass {
@Id
private String id;
private String name;
private Type type;
public static enum Type { X , Y, Z}
}
fissi che facendo variabili membro finale
@Data
@RequiredArgsConstructor
@NoArgsConstructor(access=AccessLevel.PRIVATE, force=true)
@Entity
public class Someclass {
@Id
private final String id;
private final String name;
private final Type type;
public static enum Type { X , Y, Z}
}