Bean Validation in JPA

Die Datenvalidierung, einschließlich Persistenz, ist eine allgemeine Task, die in allen Schichten einer Anwendung ausgeführt wird. Java™ Persistence API (JPA) unterstützt die Bean Validation API, damit die Datenvalidierung zur Laufzeit durchgeführt werden kann. Dieser Artikel enthält ein Einsatzszenario, in dem Bean Validation in der JPA-Umgebung einer Beispielanwendung für eine digitale Bildsammlung verwendet wird.

Die Bean Validation API ermöglicht in Umgebungen mit Java Enterprise Edition (Java EE) und Java Platform, Standard Edition (JSE) eine technologieübergreifende nahtlose Validierung. Diese Technologien umfassen zusätzlich zu JPA auch JavaServer Faces (JSF) und Java EE Connector Architecture (JCA). Weitere Informationen zu Bean Validation finden Sie im Artikel "Bean Validation API".

Es gibt drei Bean-Validation-Basiskonzepte: Integritätsbedingungen, Behandlung von Verstößen gegen Integritätsbedingungen (ungültige Integritätsbedingungen) und Validator. Wenn Sie Anwendungen in einer integrierten Umgebung wie JPA ausführen, ist keine direkte Schnittschnelle zum Validator erforderlich.

Integritätsbedingungen für Bean Validation sind Annotationen oder XML-Code, der einer Klasse, einem Feld oder einer Methode einer JavaBeans-Komponente hinzugefügt wird. Integritätsbedingungen können integriert oder benutzerdefiniert sein. Sie werden verwendet, um reguläre Integritätsbedingungsdefinitionen zu definieren und um Integritätsbedingungen zu erstellen. Die integrierten Integritätsbedingungen werden von der Spezifikation Bean Validation definiert und sind für jeden Validation-Provider verfügbar. Eine Liste der integrierten Integritätsbedingungen finden Sie im Artikel "Integrierte Integritätsbedingungen für Bean Validation". Wenn Sie andere Integritätsbedingungen benötigen als die integrierten, können Sie eigene Integritätsbedingungen erstellen.

Integritätsbedingungen und JPA

Das folgende Einsatzszenario veranschaulicht, wie eine integrierte Integritätsbedingungen in der JPA-Architektur einer Beispiel für eine digitale Bildsammlung verwendet wird.

Im ersten Codebeispiel wird eine integrierte Integritätsbedingung einer einfachen Entität des JPA-Modells mit dem Namen image (Bild) hinzugefügt. Ein Bild verfügt über eine ID, einen Bildtyp, einen Dateinamen und Bilddaten. Der Bildtyp muss angegeben werden, und der Dateiname des Bilds muss eine gültige JPEG- oder GIF-Erweiterung enthalten Der Code zeigt die mit Annotationen versehene Entität "Image" (Bild) mit einigen angewendeten integrierten Integritätsbedingungen für Bean-Validierung.
package org.apache.openjpa.example.gallery.model;

import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;

@Entity 
public class Image {

    private long id;
    private ImageType type;
    private String fileName;
    private byte[] data;

    @Id 
    @GeneratedValue
    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    @NotNull(message="Image type must be specified.")
    @Enumerated(EnumType.STRING)
    public ImageType getType() {
        return type;
    }

    public void setType(ImageType type) {
        this.type = type;
    }

    @Pattern(regexp = ".*\\.jpg|.*\\.jpeg|.*\\.gif",
        message="Only images of type JPEG or GIF are supported.")
    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public byte[] getData() {
        return data;
    }

    public void setData(byte[] data) {
        this.data = data;
    }
}

Die Klasse "Image" verwendet zwei integrierte Integritätsbedingungen, @NotNull und @Pattern. Mit der Integritätsbedingung @NotNull wird sichergestellt, dass ein Element des Typs "ImageType" (Bildtyp) angegeben wird, und die Integritätsbedingung @Pattern verwendet eine Mustererkennung für reguläre Ausdrücke, um sicherzustellen, dass der Name der Bilddatei eine Erweiterung verwendet, die mit einem unterstützten Bildformat übereinstimmt. Jede Integritätsbedingung verfügt über eine zugehörige Validierungslogik, die zur Ausführungszeit gestartet wird, wenn die Entität "Image" (Bild) ausgewertet wird. Wird eine der Integritätsbedingungen nicht erfüllt, löst der JPA-Provider eine Ausnahme des Typs "ConstraintViolationException" mit einer definierten Nachricht aus. Die Spezifikation JSR-303 unterstützt auch die Verwendung von Variablen im Nachrichtenattribut. Die Variable referenziert eine Nachricht mit Schlüssel in einem Ressourcenpaket. Das Ressourcenpaket unterstützt umgebungsspezifische Nachrichten sowie die Globalisierung, Übersetzung und Eignung für kulturübergreifenden Einsatz von Nachrichten.

Sie können eigene angepasster Validator und Integritätsbedingungen erstellen. Im vorherigen Beispiel verwendet die Entität "Image" die Integritätsbedingung "@Pattern", um den Dateinamen des Bilds zu validieren. Sie führt jedoch keine Prüfung auf Integritätsbedingungen für die eigentlichen Bilddaten durch. Sie können eine musterbasierte Integritätsbedingung verwenden. Allerdings hätten Sie dadurch nicht dieselbe Flexibilität wie bei Verwendung einer Integritätsbedingung, die speziell dazu erstellt wurde, die Daten auf Integritätsbedingungen zu prüfen. In diesem Fall können Sie eine angepasste Integritätsbedingungsannotationen auf Methodenebene erstellen. Nachfolgend wird eine angepasste bzw. benutzerdefinierte Integritätsbedingung mit dem Namen "ImageContent" (Bildinhalt) gezeigt.
package org.apache.openjpa.example.gallery.constraint;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import javax.validation.Constraint;
import javax.validation.Payload;

import org.apache.openjpa.example.gallery.model.ImageType;

@Documented
@Constraint(validatedBy = ImageContentValidator.class)
@Target({ METHOD, FIELD })
@Retention(RUNTIME)
public @interface ImageContent {
    		String message() default "Image data is not a supported format.";
    		Class<?>[] groups() default {};
		Class<? extends Payload>[] payload() default {};
				ImageType[] value() default { ImageType.GIF, ImageType.JPEG };
}
Als Nächstes müssen Sie die Validatorklasse "ImageContentValidator" erstellen. Die Logik in diesem Validator wird vom Valdiation-Provider implementiert, wenn die Integritätsbedingung validiert wird. Die Validatorklasse wird über das Attribut "validatedBy" in der Annotation "@Constraint" an die Integritätsbedingungsannotation gebunden, wie im folgenden Beispiel gezeigt wird:
package org.apache.openjpa.example.gallery.constraint;
import java.util.Arrays;
import java.util.List;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.apache.openjpa.example.gallery.model.ImageType;
/**
 * Einfache Prüfung, ob das Dateiformat unterstützt wird
 */
public class ImageContentValidator implements ConstraintValidator<ImageContent, byte[]> {
    private List<ImageType> allowedTypes = null;
    /**      
     * Integritätsbedingungsvalidator basierend auf den zu unterstützenden Bildtypen
     * konfigurieren.     * @param constraint Die Definition der Integritätsbedingungsdefinition.
     */     
    public void initialize(ImageContent constraint) {         
        allowedTypes = Arrays.asList(constraint.value());     
    }      
    /**      
     * Angegebenen Wert validieren.      */     
    public boolean isValid(byte[] value, ConstraintValidatorContext context) {
        if (value == null) {             
            return false;
        }
        // Prüfen, ob der GIF-Header GIF87 oder GIF89 ist.
        if (allowedTypes.contains(ImageType.GIF)) {
            String gifHeader = new String(value, 0, 6);
            if (value.length >= 6 &&
                (gifHeader.equalsIgnoreCase("GIF87a") ||
                 gifHeader.equalsIgnoreCase("GIF89a"))) {
                return true;
            }
        }
        // Überprüfen, ob JPEG mit SOI beginnt und auf EOI endet
        if (allowedTypes.contains(ImageType.JPEG)) {
            if (value.length >= 4 &&
                value[0] == 0xff && value[1] == 0xd8 &&
                value[value.length - 2] == 0xff && value[value.length -1] == 0xd9) {
                return true;
            }
        }
        // Unbekanntes Dateiformat
        return false;
    }
}
Wenden Sie diese neue Integritätsbedingung auf die Methode "getData()" der Klasse "Image" an. Beispiel:
@ImageContent
    public byte[] getData() {
        return data;
    }
Bei der Validierung des Datenattributs wird die Methode "isValid()" in ImageContentValidator gestartet. Diese Methode enthält Logik für die Durchführung einer einfachen Prüfung des Formats der binären Bilddaten. Ein Feature in ImageContentValidator, das unter Umständen übersehen wird, ist die Validierung eines bestimmten Bildtyps. Laut Definition werden die Formate JPEG und GIF akzeptiert, aber es kann auch geprüft werden, ob ein ganz bestimmtes Format verwendet wird. Wenn Sie die Annotation beispielsweise in das folgende Codebeispiel ändern, können Sie den Validator dazu anweisen, nur Bilddaten mit dem gültigen JPEG-Inhalt zuzulassen.
@ImageContent(ImageType.JPEG)
    public byte[] getData() {
        return data;
    }
Integritätsbedingungen auf Typebene sind ebenfalls eine Option, weil Sie für eine Entität möglicherweise Kombinationen von Attributen auswerten müssen. In den vorherigen Beispielen werden Bean-Validation-Integritätsbedingungen für einzelne Attribute verwendet. Integritätsbedingungen auf Typebene ermöglichen eine Validierung mehrerer Attribute. Beispielsweise prüfen die auf die Entität "Image" angewendeten Integritätsbedingungen, ob ein Bildtyp festgelegt (nicht null) ist, ob die Erweiterung im Bilddateinamen unterstützt wird und ob für den angegebenen Typ das richtige Datenformat verwendet wird. Es wird aber beispielsweise nicht kollektiv geprüft, ob eine Datei mit dem Namen img0.gif den Typ GIF hat und das Format der Daten für eine GIF-Bilddatei gültig ist. Weitere Informationen zu Integritätsbedingungen auf Typebene finden Sie im White Paper "OpenJPA Bean Validation Primer" im Abschnitt "Type-level constraints."

Validierungsgruppen

Die Bean-Validierung verwendet Validierungsgruppen, um festzustellen, welche Art der Validierung wann ausgeführt wird.

Es müssen keine speziellen Schnittstellen implementiert oder Annotationen angewendet werden, um eine Validierungsgruppe zu erstellen. Eine Validierungsgruppe wird mit einer Klassendefinition angegeben.
Bewährtes Verfahren Bewährtes Verfahren: Wenn Sie Gruppen verwenden, sollten Sie einfache Schnittstellen verwenden. Wenn Sie eine einfache Schnittstelle verwenden, erhöht sich die Wiederverwendbarkeit von Validierungsgruppen in mehreren Umgebungen. Die Verwendung einer Klasse oder eine Entitätsdefinition als Validierungsgruppe hingegen kann das Objektmodell einer anderen Anwendung belasten, indem Domänenklassen und Logik eingebracht werden, die für die Anwendung keinen Sinn machen. Wenn in einer bestimmten Integritätsbedingung keine Validierungsgruppen angegeben sind, wird standardmäßig die Gruppe "javax.validation.groups.Default" für die Validierung verwendet. Das Erstellen einer angepassten Gruppe ist so einfach wie die Erstellung einer neuen Schnittstellendefinition. bprac

Weitere Informationen zu Validierungsgruppen mit OpenJPA finden Sie im White Paper "OpenJPA Bean Validation Primer" und im Abschnitt zu den Validierungsgruppen.

JPA-Domänenmodell

Zusätzlich zur Entität "Image" gibt es die persistenten Entitäten "Album", "Creator" und "Location". Die Entität "Album" enthält eine Referenz auf die Sammlung der zugehörigen Imageentitäten. Die Entität "Creator" enthält eine Referenz auf die Album-Entitäten, die der Bildersteller (Creator) beiträgt, und eine Referenz auf die erstellten Imageentitäten. Damit können Sie alle Funktionen für die Navigation zwischen den einzelnen Entitäten in der Domäne nutzen. Dem Bild wurde eine integrierbare Position hinzugefügt, um das Speichern von Informationen zur Bildposition zusammen mit dem Bild zu ermöglichen.

Die Entitäten "Album" und "Creator" haben integrierte Standardintegritätsbedingungen. Die integrierbare Position ist spezifischer, da sie die Verwendung der Annotation @Valid für die Validierung integrierter Objekte zeigt. Um die Position in ein Bild zu integrieren, werden der Klasse "Image" ein neues Feld und die zugehörigen persistenten Eigenschaften hinzugefügt. Beispiel:
private Location location;

    @Valid
    @Embedded
    public Location getLocation() {
        return location;
    }

    public void setLocation(Location location) {
        this.location = location;
    }
Die Annotation "@Valid" stellt in einer JPA-Umgebung eine Verkettungsprüfung integrierbarer Objekte bereit. Aus diesem Grund werden beim Validieren des Bilds auch alle Integritätsbedingungen für die von ihm referenzierte Position ausgewertet. Wenn @Valid nicht angegeben ist, wird die Position nicht ausgewertet. In einer JPA-Umgebung wird die verkettete Validierung über @Valid nur für integrierbare Objekte unterstützt. Referenzierte Entitäten und Sammlungen von Entitäten werden getrennt voneinander validiert, um eine zirkuläre Validierung zu verhindern.

Bean Validation und die JPA-Umgebung

Die Spezifikation JPA vereinfacht die Integration mit der Bean Validation API. In einer JSE-Umgebung wird Bean Validation standardmäßig aktiviert, wenn Sie die Bean Validation API und einen Bean-Validation-Provider in Ihrem Laufzeitklassenpfad bereitstellen. In einer Umgebung von Java EE enthält der Anwendungsserver einen Bean-Validierungsprovider, daher ist es nicht erforderlich, diesen in das Anwendungspaket aufzunehmen. In beiden Umgebungen muss die Datei persistence.xml ab Version 2.0 verwendet werden.

Die Datei persistence.xml der Version 1.0 bietet keine Möglichkeit, die Bean-Validierung zu konfigurieren. Durch die Anforderung, dass die Datei persistence.xml ab Version 2.0 verwendet werden muss, wird verhindert, dass eine reine JPA-1.0-Anwendung den Aufwand des Validierungsstarts und der Validierungsausführung eingeht. Dies ist wichtig, weil einer auf Version 1.0 basierenden Anwendung keine Möglichkeiten zur Inaktivierung der Validierung zur Verfügung stehen. In einer Umgebung von Java EE können sie die Validierung in einer vorhandenen Anwendung der Version 1.0 aktivieren, indem Sie das Stammelement der Datei persistence.xml ändern. Im folgenden Beispiel wird die Datei persistence.xml dargestellt:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
								http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
    version="2.0" >
...
</persistence>
Bean Validation unterstützt drei Betriebsmodi in der JPA-Umgebung:
  • Auto

    Aktiviert Bean Validation, wenn ein Validation-Provider im Klassenpfad vorhanden ist. Auto ist die Standardeinstellung.

  • Callback

    Wenn der Modus "Callback" angegeben ist, muss ein Bean-Validation-Provider für den JPA-Provider verfügbar sein. Wenn nicht, löst der JPA-Provider bei der Instanziierung einer neuen JAP-Entitätsmanagerfactory eine Ausnahme aus.

  • Ohne

    Inaktiviert Bean Validation für eine bestimmte Persistenzeinheit.

Der Modus "Auto" vereinfacht die Implementierung, kann aber zu Problemen führen, wenn die Validierung aufgrund eines Konfigurationsproblems nicht stattfindet.
Bewährtes Verfahren Bewährtes Verfahren: Verwenden Sie entweder den Modus "None" oder den Modus "Callback", um ein konsistentes Verhalten zu gewährleisten.bprac
Wenn Sie "none" angeben, führt JPA beim Start außerdem eine Optimierung durch und versucht keine unerwartete Validierung. Eine explizite Inaktivierung der Validierung ist insbesondere in einer Umgebung von Java EE wichtig, in der der Container einen Validierungsprovider bereitstellen muss. Deshalb ist die Validierung in einer Anwendung ab JPA Version 2.0, die in einem Container gestartet wird, aktiviert, sofern nichts anderes angegeben wird. Dieser Prozess fügt der Verarbeitung der Lebenszyklusereignisse eine weitere Verarbeitung hinzu.
Es gibt zwei Methoden für die Konfiguration der Validierungsmodi in JPA. Die einfachste Art der Konfiguration ist das Hinzufügen eines Elements des Typs "validation-mode" mit dem gewünschten Validierungsmodus zur Datei persistence.xml. Beispiel:
 <persistence-unit name="auto-validation">
		        	... 
								<!-- Validierungsmodi: AUTO, CALLBACK, NONE -->
								<validation-mode>AUTO</validation-mode>
				...
		</persistence-unit>  
Eine andere Methode ist die Konfiguration des Validierungsmodus über das Programm durch Angabe der Eigenschaft "javax.persistence.validation.mode" mit dem Wert "auto", "callback" oder "none" bei der Erstellung einer neuen JPA-Entitätsmanagerfactory, wie im folgenden Beispiel gezeigt:
Map<String, String> props = new HashMap<String, String>();
				props.put("javax.persistence.validation.mode", "callback");
        EntityManagerFactory emf = 
            Persistence.createEntityManagerFactory("validation", props);
Bean Validation in JPA findet während der Verarbeitung von JPA-Lebenszyklusereignissen statt. Sofern aktiviert, findet Bean Validation in der letzten Phase der Lebenszyklusereignisse "PrePersist", "PreUpdate" und "PreRemove" statt. Da einige dieser Ereignisse die Entität ändern können, die validiert wird, findet Bean Validation erst nach allen benutzerdefinierten Lebenszyklusereignissen statt. Standardmäßig aktiviert JPA die Validierung für die Standardvalidierungsgruppe der Lebenszyklusereignisse PrePersist und PreUpdate. Wenn andere Validierungsgruppen ausgewertet werden sollen oder wenn die Validierung für das Ereignis PreRemove aktiviert werden soll, können Sie in der Datei persistence.xml die Validierungsgruppen angeben, die jedes Lebenszyklusereignis auswerten sollen. Beispiel:
<persistence-unit name="non-default-validation-groups">
				<class>my.Entity</class>
				<validation-mode>CALLBACK</validation-mode>
		<properties>
						<property name="javax.persistence.validation.group.pre-persist"
       value="org.apache.openjpa.example.gallery.constraint.SequencedImageGroup"/>
						<property name="javax.persistence.validation.group.pre-update"
       value="org.apache.openjpa.example.gallery.constraint.SequencedImageGroup"/>
						<property name="javax.persistence.validation.group.pre-remove"
       value="javax.validation.groups.Default"/>
		</property>
		</persistence-unit>
Das folgende Beispiel zeigt verschiedene Phasen des JPA-Lebenszyklus, einschließlich "persist", "update" und "remove":
EntityManagerFactory emf = 
            Persistence.createEntityManagerFactory("BeanValidation");
        EntityManager em = emf.createEntityManager();

        Location loc = new Location();
        loc.setCity("Rochester");
        loc.setState("MN");
        loc.setZipCode("55901");
        loc.setCountry("USA");

        // Bild mit nicht übereinstimmenden Typ und nicht übereinstimmender Dateierweiterung erstellen
        Image img = new Image();
        img.setType(ImageType.JPEG);
        img.setFileName("Winter_01.gif");
        loadImage(img);
        img.setLocation(loc);
        
        // *** PERSIST ***
        try  {    
            em.getTransaction().begin();
            // Entity mit nicht übereinstimmender Erweiterung und nicht übereinstimmendem Typ speichern
            em.persist(img);
        } catch (ConstraintViolationException cve) {
            // Transaktion wurde für Rollback markiert. Rollback durchführen und
            // neue Transaktion starten.
            em.getTransaction().rollback();
            em.getTransaction().begin();
            // Dateityp korrigieren und Speichern wiederholen.
            img.setType(ImageType.GIF);
            em.persist(img);
            em.getTransaction().commit();
        }

        // *** UPDATE ***
        try  {    
            em.getTransaction().begin();
            // Dateinamen in einen nicht übereinstimmenden Dateinamen ändern
            // und festschreiben, um Aktualisierung (update) auszulösen.
            img.setFileName("Winter_01.jpg");
            em.getTransaction().commit();
        }  catch (ConstraintViolationException cve) {
            // Ausnahme behandeln. Festschreibung (commit) ist fehlgeschlagen,
            // deshalb wurde bereits ein Rollback der Transaktion durchgeführt.
            handleConstraintViolation(cve);
        }
        // Der Aktualisierungsfehler hat zur Freigabe des Bilds geführt. Es
        // muss dem Persistenzkontext wieder hinzugefügt werden.
        img = em.merge(img);

        // *** REMOVE ***
        em.getTransaction().begin();
        try  {    
            // Typ entfernen und festschreiben, um Entfernen auszulösen
            img.setType(ImageType.GIF);
            em.remove(img);
        }  catch (ConstraintViolationException cve) {
            // Rollback the active transaction and handle the exception
            em.getTransaction().rollback();
            handleConstraintViolation(cve);
        }
        em.close();
        emf.close();

Ausnahmen

In jeder Phase des JPA-Lebenszyklus können Gültigkeitsfehler auftreten.

Wenn die Validierung einer oder mehrerer Integritätsbedingungen während eines Lebenszyklusereignisses scheitert, wird vom JPA-Provider eine Ausnahme des Typs "ConstraintViolationException" ausgelöst. Die vom JPA-Provider ausgelöst Ausnahme "ConstraintViolationException" enthält eine Gruppe von ConstraintViolations, die aufgetreten sind. Die einzelnen ungültigen Integritätsbedingungen enthalten Informationen zur Integritätsbedingung. Dazu gehören eine Nachricht, die Stamm-Bean oder JPA-Entität, die Blatt-Bean, die bei der Validierung von in JPA integrierbaren Objekten verwendet wird, die Attribute, die nicht ausgewertet werden konnten sowie den Wert, der den Fehler verursacht hat. Im Folgenden sehen Sie eine Beispielausnahmebehandlungsroutine:
private void handleConstraintViolation(ConstraintViolationException cve) {
      Set<ConstraintViolation<?>> cvs = cve.getConstraintViolations();
						for (ConstraintViolation<?> cv : cvs) {
										System.out.println("------------------------------------------------");
          		System.out.println("Violation: " + cv.getMessage());
          		System.out.println("Entity: " + cv.getRootBeanClass().getSimpleName());
          		// Der Verstoß ist in der Leaf-Bean (integrierbar) aufgetreten.
          		if (cv.getLeafBean() != null && cv.getRootBean() != cv.getLeafBean()) {
              System.out.println("Embeddable: " + 
cv.getLeafBean().getClass().getSimpleName());
          }
          System.out.println("Attribute: " + cv.getPropertyPath());
          System.out.println("Invalid value: " + cv.getInvalidValue());
      }
    }
Die Verarbeitung ungültiger Integritätsbedingungen ist in der Regel einfach, wenn Integritätsbedingungen auf Attributebene verwendet werden. Wenn Sie einen Validator auf Typebene mit Integritätsbedingungen auf Typebene verwenden, kann es komplizierter sein, die Attribute oder die Kombination von Attributen zu ermitteln, deren Validierung gescheitert ist. Außerdem wird das gesamte Objekt als ungültiger Wert und nicht nur ein einzelnes Attribut zurückgegeben. In Fällen, in denen spezielle Informationen zum Fehler benötigt werden, können, wie in der Spezifikation "Bean Validation" beschrieben, eine Integritätsbedingung auf Attributebene oder angepasste Informationen zur ungültigen Integritätsbedingung bereitgestellt werden.

Beispiel

Das in diesem Artikel beschriebene Einsatzszenario für das JPA-Modell und die Anwendung für eine Bildersammlung kann über ein Beispiel implementiert werden, das im White Paper OpenJPA Bean Validation Primer beschrieben wird.


Symbol, das den Typ des Artikels anzeigt. Konzeptartikel



Symbol für Zeitmarke Letzte Aktualisierung: 25.05.2016
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=cdat_beanvaljpa
Dateiname:cdat_beanvaljpa.html