Jakarta Enterprise V2

Kapitel 12 · Validation

Jakarta Validation

Typ: Spezifikation / APIKategorie: ValidationPrioritaet: 10/10

Bean Validation fuer DTOs, Entities, Parameter und Business-Regeln.

Diagramm: Jakarta Validation

Fachliche Einordnung

Jakarta Validation ist im Enterprise-Kontext kein isoliertes Thema. Es beantwortet die Frage, welche Verantwortung an welcher Stelle im System liegen soll. In einem Order-&-Billing-System entscheidet diese Ebene darueber, ob eine Bestellung nachvollziehbar angenommen, validiert, persistiert, abgerechnet und an Partner- oder Legacy-Systeme weitergegeben werden kann.

Persistenz ist in Enterprise-Systemen selten nur CRUD. Es geht um Aggregatgrenzen, Transaktionslaenge, Lazy Loading, Sperrverhalten, Batchgroessen, Datenbank-Indizes und Nachvollziehbarkeit. Eine gute Jakarta-Architektur verbirgt JPA nicht, aber kapselt sie so, dass Fachlogik nicht von EntityManager-Details dominiert wird.

Technisches Modell

Das wichtigste mentale Modell lautet: API und Implementierung sind getrennt. Jakarta definiert Standards und Annotationen; die konkrete Runtime oder Library liefert das Verhalten. Dadurch kann dieselbe Fachidee auf Open Liberty, WildFly, Payara, TomEE, GlassFish oder in cloud-nativen Frameworks unterschiedlich betrieben werden.

GrenzeWelche Klasse ist Rand, Anwendung, Domain oder Infrastruktur?
FehlerfallValidierung, Timeout, Rollback, Retry und DLQ bewusst festlegen.
BetriebLogs, Metriken, Health, Traces und Konfiguration sichtbar machen.
Migration`javax.*`, Server-DDs und Provider-Features inventarisieren.

Ausfuehrliches Beispiel

java
public record CreateOrderRequest(
        @NotBlank String customerId,
        @Size(min = 1, max = 50) List<@Valid OrderLineRequest> lines) { }

public record OrderLineRequest(
        @NotBlank String articleNo,
        @Min(1) int quantity,
        @DecimalMin("0.01") BigDecimal netPrice) { }

@Constraint(validatedBy = BusinessDayValidator.class)
@Target({FIELD, PARAMETER})
@Retention(RUNTIME)
public @interface BusinessDay {
    String message() default "must be a business day";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

public class BusinessDayValidator implements ConstraintValidator<BusinessDay, LocalDate> {
    public boolean isValid(LocalDate value, ConstraintValidatorContext context) {
        return value != null && value.getDayOfWeek().getValue() <= 5;
    }
}

Typische Fehler und bessere Variante

1. Fachlogik im technischen Adapter

Besser: Resource, Servlet oder Listener nur als Adapter nutzen. Die Entscheidung liegt in Application Service und Domain-Modell.

2. Zu breite Transaktion

Besser: Transaktionsgrenzen am Use Case schneiden, externe Calls ausserhalb oder ueber Outbox/JMS entkoppeln.

3. Provider-Magie ohne Dokumentation

Besser: Jede Implementierungsentscheidung in README, ADR oder design-patterns.md vermerken.

4. Keine Betriebsdiagnose

Besser: fachliche IDs, Trace-ID, Health Checks und technische Metriken von Anfang an einbauen.

Praxis-Checkliste

  • Typ klar markiert: Spezifikation, Framework, Library, Runtime oder Methodik.
  • Codebeispiel trennt Adapter, Application Service, Domain und Infrastruktur.
  • Fehlerfall, Security und Transaktion sind erkennbar.
  • Migration von Java EE zu Jakarta EE wurde beachtet.
  • Teststrategie mit Unit-, Integration- oder Container-Test ist ableitbar.

Verwandte Kapitel