19 Stimmen

Expliziter Konstruktor mit Lombok?

Ich schreibe gerade einen chaotischen Code um, der eine Datenbank verwaltet, und habe gesehen, dass der ursprüngliche Programmierer eine Klasse erstellt hat, die der Datenbank wie folgt zugeordnet ist:

(Ich habe unnötigen Code entfernt, der in dieser Frage keinen Zweck hat)

@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;
    }
}

Ich bin noch ein Anfänger in Hibernate und der Verwendung von Lombok, aber würde dies nicht das Gleiche tun und würde Lombok nicht automatisch den benötigten Konstruktor für Sie erstellen?

@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());
}

Außerdem sagt der ursprüngliche Programmierer dieses Codes, dass er zulässt, dass der Header "null" ist, aber er hat ausdrücklich einen Konstruktor erstellt, der einen Wert für den Header benötigt. Übersehe ich etwas oder ist das ein bisschen widersprüchlich?

20voto

Tim Punkte 19225

Werfen Sie einen Blick auf @NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor .

Das Konstruktorverhalten von @Data ist wie @RequiredArgsConstructor :

@RequiredArgsConstructor erzeugt eine Konstruktor mit 1 Parameter für jedes Feld, das eine besondere Behandlung erfordert. Alle endgültigen Felder erhalten einen Parameter, sowie sowie alle Felder, die als @NonNull markiert sind, die nicht dort initialisiert werden, wo sie deklariert sind.

Da keines Ihrer Felder entweder final ou @NonNull wird dies zu einem Konstruktor ohne Argumente führen. Dies ist jedoch nicht der aussagekräftigste Weg, um dieses Verhalten zu erreichen.

Was Sie in diesem Fall wahrscheinlich brauchen, ist eine @NoArgsConstructor (wahlweise kombiniert mit einem @AllArgsConstructor ), um das beabsichtigte Verhalten klar zu kommunizieren, wie es auch in der Dokumentation angegeben ist:

Bestimmte Java-Konstrukte, wie z.B. hibernate und der Dienstanbieter Schnittstelle erfordern einen no-args Konstruktor. Diese Annotation ist nützlich hauptsächlich in Kombination mit entweder @Data oder einer der anderen Konstruktor erzeugenden Annotationen.

1voto

DeliveryNinja Punkte 827

Dieser Teil ist widersprüchlich, da haben Sie recht. Ich habe Lombok noch nicht verwendet, aber mit Hibernate, wenn Sie in der Lage sein wollen, eine Bean zu erstellen und zu persistieren, benötigen Sie den Standardkonstruktor wie oben angegeben, soweit ich weiß. Er verwendet Constructor.newInstance(), um neue Objekte zu instanziieren.

Hier finden Sie eine Hibernate-Dokumentation, die mehr ins Detail geht.

Hibernate-Dokumentation

1voto

Jules0707 Punkte 595

Wenn Sie @Data mit einem @NonNull-Feld verwenden und trotzdem einen noargs-Konstruktor wünschen, sollten Sie versuchen, alle 3 Annotationen zusammen hinzuzufügen

@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor

Offenbar eine alte intelliJ Fehler, den ich in Eclipse Kepler und lombok v0.11.4 repliziert habe

0voto

z atef Punkte 6151
@NoArgsConstructor, 
@RequiredArgsConstructor, 
@AllArgsConstructor

Erzeugen Sie Konstruktoren, die keine Argumente, ein Argument pro finalem / nicht-nullem Feld oder ein Argument für jedes Feld benötigen. Dies lesen lombok-projekt

@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}
}

Das Problem wurde behoben, indem die Mitgliedsvariablen endgültig gemacht wurden.

@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}
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X