GEDOPLAN
Jakarta EE (Java EE)Java SE

Lombok – oder die Geschichte von dem, der auszog, Boilerplate Code zu vertreiben

Jakarta EE (Java EE)Java SE

Der Sprache Java wird häufig angelastet, bei der Definition von Klassen zu viel unnützen – “Boilerplate” – Code zu benötigen. So werden fachliche Attribute i. A. in privaten Instanzvariablen abgelegt, für die dann öffentliche Getter und/oder Setter benötigt werden. Zudem sollte nahezu jede Klasse eine Implementierung der Methoden equals und hashCode besitzen. Und toString wäre auch ganz schön. Neben dem eigentlich wichtigen Inhalt einer Klasse muss also noch eine Menge Code geschrieben werden, der auch generiert werden könnte. Dies kann man natürlich mit Hilfe der gängigen IDEs tun, was aber nur bei der ersten Erstellung der Klassen hilft. Bei späteren Änderungen – Attribute kommen hinzu oder fallen weg, Attributtypen ändern sich – ist eine aufwändigere, meist mauelle Anpassung unumgänglich.

Hier bietet das Projekt Lombok eine andere Herangehensweise: Die Klassen werden durch Annotationen angereichert und ein Annotation Processor erzeugt den Code zur Build-Zeit. Die wesentlichen Annotationen sind diese:

  • @Getter, @Setter
    fügen zu einem Attribut eine Getter- bzw. Setter-Methode hinzu. Auf Klassenebene angewendet, werden die Methoden für alle Attribute erzeugt, die keine eigene Annotation besitzen.
  • @EqualsAndHashCode
    erzeugt die Methoden equals und hashCode auf Basis aller oder einzelner Attribute.
  • @Data
    entspricht @Getter @Setter @EqualsAndHashCode. Zusätzlich wird auch ein Konstruktor erzeugt.

Eine detailierte Beschreibung dieser Annotationen sowie weiterer Bestandteile von Lombok findet man hier.

Zur Einbindung in Maven-Projekte reicht es, die folgende Dependency aufzunehmen:

<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.16.8</version>
</dependency>

Neben den zur Laufzeit benötigten Klassen enthält die Bibliothek auch den erwähnten Annotation Processor, der die Generierung des zusätzlichen Programmcodes übernimmt.

Eclipse benötigt zur Integration von Lombok einen Java-Agenten. Er kann der Eclipse-Konfiguration durch Ausführung des Lombok-JAR-Files hinzugefügt werden: java -jar lombok-1.18.8.jar. Das Tool findet ggf. installierte Eclipse-Versionen nicht selbstständig. In dem Fall muss man im angezeigten Dialog das Eclipse-Verzeichnis angeben, in dem sich die Konfigurationsdatei eclipse.ini befindet (bzw. jbdevstudio.ini beim JBoss Developer Studio). Welche Änderungen das Tool an der Eclipse-Installation vornehmen wird, kann man sich zunächst anzeigen lassen.
NetBeans benötigt keine besondere Einstellung für Lombok, soweit die bearbeiteten Projekte Maven-Projekte sind (s. o.).
Für IntelliJ gibt es ein Lombok-Plugin, das aktiviert werden muss.

Für einfache Fachobjekte eignet sich @Data recht gut. Damit werden Getter, Setter, equals, hashCode und toString auf Basis aller Attribute bereitgestellt (s. Beispiel aus der Lombok-Doku).

Für JPA-Entities ist @Data aber zu starr: Zum einen wird ein Standardkonstruktor (ohne Parameter) benötigt, zum anderen sollen equals und hashCode nur die Id-Attribute benutzen. Daher sollten statt @Data eher die einzelnen Annotationen @Getter etc. verwendet und die Attributliste für @EqualsAndHashCode auf die Id-Attribute eingeschränkt werden:

@Entity
@Getter
@Setter
@EqualsAndHashCode(of = "isoCode")
@ToString
public class Country
{
  @Id
  private String    isoCode;

Für Entity-Klassen mit generierter Id reicht aber auch das nicht, da equals bei noch nicht gesetzter Id (null) in min.einem der beiden verglichenen Objekte false zurückgeben sollte. Die von Lombok generierte Methode liefert aber true.

Best Practice bei GEDOPLAN ist es daher, Entity-Klassen von einer der von uns geschriebenen Basisklassen SingleIdEntity, StringIdEntity, GeneratedIntegerIdEntity etc. abzuleiten. equals, hashCode und toString sind dann in der Basisklasse bereits korrekt implementiert. Die Lombok-Annotationen @EqualsAndHashCode und @ToString sind dann nutzlos bzw. kontraproduktiv. @Getter und @Setter können aber sinnvoll eingesetzt werden:

@Entity
@Access(AccessType.FIELD)
@Getter
@Setter
public class City extends GeneratedIntegerIdEntity
{

Die erwähnten Basisklassen stammen aus unserer Bibliothek baselibs-persistence, die mit folgender Maven-Dependency einbezogen werden kann:

<dependency>
  <groupId>de.gedoplan</groupId>
  <artifactId>baselibs-persistence</artifactId>
  <version>1.0.30</version>
</dependency>

An gleicher Stelle liegen auch die Sourcen dieser Klassen, wenn Sie dort mal hineinschauen möchten.

In https://github.com/GEDOPLAN/lombok-demo steht ein Showcase zum Anschauen und Ausprobieren bereit.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Bitte füllen Sie dieses Feld aus.
Bitte füllen Sie dieses Feld aus.
Bitte gib eine gültige E-Mail-Adresse ein.
Sie müssen den Bedingungen zustimmen, um fortzufahren.

Autor

Diesen Artikel teilen

LinkedIn
Xing

Gibt es noch Fragen?

Fragen beantworten wir sehr gerne! Schreibe uns einfach per Kontaktformular.

Kurse

weitere Blogbeiträge

IT-Training - GEDOPLAN
Webprogrammierung

Angular, HTTP Error Handler

Eine Rest-Schnittstelle über den von Angular bereitgestellten HTTP-Service an zu binden ist nicht schwer. Dank Observables ist auch die Fehlerbehandlung…
openapi 1
Webprogrammierung

Angular + OpenAPI Generator

In einem älteren Posting haben wir schon einmal einen Blick auf Swagger geworfen, eine charmante Möglichkeit aus den eigenen Rest-Schnittstellen…

Work Life Balance. Jobs bei Gedoplan

We are looking for you!

Lust bei GEDOPLAN mitzuarbeiten? Wir suchen immer Verstärkung – egal ob Entwickler, Dozent, Trainerberater oder für unser IT-Marketing! Schau doch einfach mal auf unsere Jobseiten! Wir freuen uns auf Dich!

Work Life Balance. Jobs bei Gedoplan

We are looking for you!

Lust bei GEDOPLAN mitzuarbeiten? Wir suchen immer Verstärkung – egal ob Entwickler, Dozent, Trainerberater oder für unser IT-Marketing! Schau doch einfach mal auf unsere Jobseiten! Wir freuen uns auf Dich!