9. Erstellung der Datenbanken aus den Entitäten JPA
Es ist möglich, die Tabellen einer Datenbank anhand der Entitäten JPA zu erstellen. Dies zeigen wir nun. Der Vorteil besteht darin, zu überprüfen, ob die anhand der Entitäten JPA generierte Datenbank tatsächlich die gewünschte ist.
9.1. Einrichtung der Arbeitsumgebung
Wir arbeiten zunächst mit einer Implementierung der Entitäten JPA, EclipseLink und [1].
![]() |
Anschließend löschen wir die Tabellen der Datenbank MySQL und [dbproduitscategories] mit dem Client [MyManager] (siehe Abschnitt 23.5). Zunächst löschen wir die Tabellen, die die Fremdschlüssel [1-3] enthalten:
![]() |
Anschließend beginnen wir erneut mit den drei verbleibenden Tabellen [4-6]:
![]() |
Das Gleiche tun wir mit der Tabelle [dbproduits], die von den Projekten [spring-jdbc-01 à 03] verwendet wird:
![]() | ![]() |
Außerdem müssen die beiden Generierungsprojekte der beiden Datenbanken importiert werden:
![]() |
- In [1] wird das Projekt [generic-create-dbproduits] importiert, das sich in [<exemples>/spring-database-generic/spring-jpa] und [2] befindet;
![]() |
- in [4] wird das Projekt [generic-create-dbproduitscategories] importiert, das sich in [<exemples>/spring-database-generic/spring-jpa] und [5] befindet;
Hinweis: Drücken Sie Alt-F5 und regenerieren Sie alle Maven-Projekte;
9.2. Generierung der Datenbank [dbproduitscategories]
![]() |
9.2.1. Maven-Konfiguration
Die Datei [pom.xml] des Projekts lautet wie folgt:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>dvp.spring.database</groupId>
<artifactId>generic-create-dbproduitscategories</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>generic-create-dbproduitscategories</name>
<description>création de la bases de données [dbproduitscategories] à l'aide des annotations JPA</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.3.RELEASE</version>
</parent>
<dependencies>
<!-- spring-jpa-generic -->
<dependency>
<groupId>dvp.spring.database</groupId>
<artifactId>spring-jpa-generic</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- Spring Weaver -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>spring.data.console.Main</start-class>
<java.version>1.7</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
</plugin>
</plugins>
</build>
</project>
- Zeilen 22–26: die Abhängigkeit vom Projekt [spring-jpa-generic], das in Abschnitt 6.4 behandelt wurde;
- Zeilen 28–32: die Abhängigkeit von einem Weaver, der zur Anreicherung der Entitäten JPA der Implementierungen EclipseLink und OpenJpa verwendet wird. Diese Abhängigkeit ist in der Datei [pom.xml] nicht erforderlich, aber deren JAR-Datei wird als Java-Agent verwendet. Durch das Einfügen der Abhängigkeit in die Datei [pom.xml] wird sichergestellt, dass die JAR-Datei tatsächlich verfügbar ist;
Letztendlich lauten die Abhängigkeiten wie folgt:
![]() |
9.2.2. Spring-Konfiguration
![]() |
Die Klasse [AppConfig] konfiguriert das Spring-Projekt:
package console;
import generic.jpa.config.ConfigJpa;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@Configuration
@Import({ ConfigJpa.class })
@EnableJpaRepositories(basePackages = { "console" })
public class AppConfig {
}
- Zeile 10: Die Klasse ruft die Beans der Klasse [ConfigJpa] ab. Zur Erinnerung: Diese Klasse arbeitet mit den Entitäten JPA aus der Datenbank [dbproduitscategories] (siehe Abschnitt 6.3);
- Zeile 11: Es wird festgelegt, dass das Paket [console] nach Instanzen von [CrudRepository] durchsucht werden soll;
In der Klasse [ConfigJpa] findet sich die folgende Bean (variiert je nach verwendeter Implementierung JPA):
// der Provider JPA
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
// Hinweis: Die Entitäten JPA und die Eclipselink-Konfiguration befinden sich in der Datei META-INF/persistence.xml
EclipseLinkJpaVendorAdapter eclipseLinkJpaVendorAdapter = new EclipseLinkJpaVendorAdapter();
eclipseLinkJpaVendorAdapter.setShowSql(false);
eclipseLinkJpaVendorAdapter.setDatabase(Database.MYSQL);
eclipseLinkJpaVendorAdapter.setGenerateDdl(true);
return eclipseLinkJpaVendorAdapter;
}
Wichtig ist hier Zeile 8. Sie ist in allen verwendeten Implementierungen von JPA vorhanden. Sie besagt, dass die den Entitäten JPA zugeordneten Tabellen, falls sie nicht existieren, angelegt werden müssen. Wir werden uns auf diese Eigenschaft stützen, um die Tabellen zu generieren.
9.2.3. Die Repositorys
![]() |
Die Schnittstelle [ProduitsRepository] sieht wie folgt aus:
package console;
import generic.jpa.entities.dbproduitscategories.Produit;
import org.springframework.data.repository.CrudRepository;
public interface ProduitsRepository extends CrudRepository<Produit, Long> {
}
Durch ihre Instanziierung wird die Instanziierung der Schicht JPA ausgelöst. Tatsächlich verweist die Schnittstelle in Zeile 7 auf die Entität JPA [Produit], was die Instanziierung der Schicht JPA erzwingt. Man hätte jede beliebige Schnittstelle [CrudRepository] verwenden können, die auf eine der Entitäten JPA verweist. Tatsächlich lässt sich feststellen, dass, obwohl [repository] nur auf die Entität JPA [Produit] verweist, tatsächlich alle Tabellen aller Entitäten JPA generiert werden.
9.2.4. Die ausführbare Klasse
![]() |
Die Klasse [CreateDatabase] lautet wie folgt:
package console;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class CreateDataBase {
public static void main(String[] args) {
// Es reicht aus, den Spring-Kontext zu instanziieren, um die Tabellen der Datenbank [dbproduitscategories] zu erstellen
// Außerdem ist mindestens ein Spring Data Repository erforderlich, sonst passiert nichts
System.out.println("Travail en cours...");
new AnnotationConfigApplicationContext(AppConfig.class).close();
System.out.println("Travail terminé...");
}
}
- Zeile 11: Der Spring-Kontext wird instanziiert, um ihn sofort wieder zu schließen. In diesem Kontext befindet sich die Bean [ProduitsRepository], die auf die Entitäten JPA und [Produit] verweist. Dies reicht aus, um die Schicht JPA zu instanziieren und somit die Tabellen der Datenbank [dbproduitscategories] zu generieren.
9.2.5. Generierung der Tabellen mit EclipseLink
Wir befinden uns in der folgenden Konfiguration:
![]() |
- Die Schicht [JDBC] ist für die Datenbank [dbproduitscategories] von MySQL konfiguriert;
- die Ebene [JPA] ist mit EclipseLink implementiert;
- die Datenbank [dbproduitscategories] enthält keine Tabellen;
Hinweis: Drücken Sie Alt-F5 und generieren Sie alle Maven-Projekte neu;
Es wird die folgende Ausführungskonfiguration verwendet:
![]() |
- In [1-2] benötigt diese Ausführungskonfiguration einen Java-Agenten, damit der Test erfolgreich ist. Je nach Fall benötigt EclipseLink diesen Agenten nicht immer, aber hier schlägt die Ausführung fehl, wenn er nicht vorhanden ist. Bei diesem Agenten handelt es sich nicht um einen EclipseLink-Agenten, sondern um einen Spring-Agenten. Er wird durch die Abhängigkeit bereitgestellt:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
<scope>runtime</scope>
</dependency>
die in der Datei [pom.xml] des Projekts vermerkt ist. Der Agent befindet sich in [<m2-repo>/org/springframework/spring-instrument/4.1.6.RELEASE/spring-instrument-4.1.6.RELEASE.jar], wobei <m2-repo> das lokale Maven-Repository ist;
Die Ausführung liefert das folgende Ergebnis:
![]() |
In [3] ist zu sehen, dass die Tabellen generiert wurden. Überprüfen wir nun die DDL (Domain Definition Language) der Datenbank:
![]() | ![]() |
![]() |
Das Skript SQL zur Tabellengenerierung kann ebenfalls in einer Datei mit dem Namen [1] gespeichert werden.
![]() | ![]() ![]() |
Das generierte Skript SQL lautet wie folgt:
SET FOREIGN_KEY_CHECKS=0;
USE `dbproduitscategories`;
CREATE TABLE `categories` (
`ID` BIGINT(20) NOT NULL AUTO_INCREMENT,
`NOM` VARCHAR(30) COLLATE utf8_general_ci NOT NULL,
`VERSIONING` BIGINT(20) DEFAULT NULL,
PRIMARY KEY (`ID`) USING BTREE,
UNIQUE KEY `NOM` (`NOM`) USING BTREE
) ENGINE=InnoDB
AUTO_INCREMENT=1 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'
;
CREATE TABLE `produits` (
`ID` BIGINT(20) NOT NULL AUTO_INCREMENT,
`DESCRIPTION` VARCHAR(100) COLLATE utf8_general_ci DEFAULT NULL,
`CATEGORIE_ID` BIGINT(20) NOT NULL,
`NOM` VARCHAR(30) COLLATE utf8_general_ci NOT NULL,
`PRIX` DOUBLE NOT NULL,
`VERSIONING` BIGINT(20) DEFAULT NULL,
`CATEGORIE` INTEGER(11) NOT NULL,
PRIMARY KEY (`ID`) USING BTREE,
UNIQUE KEY `NOM` (`NOM`) USING BTREE,
KEY `FK_PRODUITS_CATEGORIE_ID` (`CATEGORIE_ID`) USING BTREE,
CONSTRAINT `FK_PRODUITS_CATEGORIE_ID` FOREIGN KEY (`CATEGORIE_ID`) REFERENCES `categories` (`ID`) ON DELETE CASCADE
) ENGINE=InnoDB
AUTO_INCREMENT=1 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'
;
CREATE TABLE `roles` (
...
) ENGINE=InnoDB
AUTO_INCREMENT=1 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'
;
CREATE TABLE `users` (
...
) ENGINE=InnoDB
AUTO_INCREMENT=1 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'
;
CREATE TABLE `users_roles` (
...
) ENGINE=InnoDB
AUTO_INCREMENT=1 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'
;
Betrachten wir zum Beispiel das Skript SQL, das die Tabelle [PRODUITS] (Zeilen 15–29) generiert:
- Zeile 16: [ID] ist der Primärschlüssel (Zeile 23) mit dem Attribut [AUTO_INCREMENT] (Zeile 5). Dies entspricht den Anmerkungen [@Id, @GeneratedValue(strategy = GenerationType.IDENTITY), @Column(name = ConfigJdbc.TAB_JPA_ID)] zum Feld [id] der Entität JPA;
- Zeile 17: Die Definition der Spalte [DESCRIPTION] entspricht der Anmerkung [@Column(name = ConfigJdbc.TAB_PRODUITS_DESCRIPTION, length = 100)] des Feldes [description] der Entität JPA;
- Zeile 18: Die Spalte [CATEGORIE_ID] ist ein Fremdschlüssel der Tabelle [PRODUITS] auf die Spalte [CATEGORIES.ID] (Zeile 26). Außerdem hat dieser Fremdschlüssel das Attribut [ON DELETE CASCADE]. Dies entspricht den Anmerkungen [@ManyToOne(fetch = FetchType.LAZY), @JoinColumn(name = ConfigJdbc.TAB_PRODUITS_CATEGORIE_ID)] für das Feld [Produit.categorie] und der Anmerkung [@OneToMany(fetch = FetchType.LAZY, mappedBy = "categorie", cascade = { CascadeType.ALL }), @CascadeOnDelete] für das Feld [Categorie.produits];
- Zeile 19: Die Definition der Spalte [NOM] entspricht der Anmerkung [@Column(name = ConfigJdbc.TAB_PRODUITS_NOM, unique = true, length = 30, nullable = false)] des Feldes [Produit.nom];
- Zeile 20: Die Definition der Spalte [PRIX] entspricht der Anmerkung [@Column(name = ConfigJdbc.TAB_PRODUITS_PRIX, nullable = false)] des Feldes [Produit.prix];
- Zeilen 24–25: Das Skript erstellt drei Indizes für jede der eindeutigen Spalten der Tabelle;
Die generierten Tabellen haben keinen Standardwert für das Feld VERSIONING, während der Java-Code einen solchen erwartet. Fehlt dieser Standardwert, werden bestimmte Tests nicht bestanden. Dieses Attribut wird wie folgt hinzugefügt:
![]() |
![]() |
![]() |
Dies wird für alle fünf Tabellen durchgeführt, die die Spalte [VERSIONING] enthalten. Der Wert des Standardwerts spielt keine Rolle. Er muss lediglich vorhanden sein. Anschließend wird er bei jeder Änderung der Zeile, zu der er gehört, um 1 erhöht.
Überprüfen Sie anschließend, ob die folgenden Ausführungskonfigurationen erfolgreich sind:
- [spring-jdbc-generic-04.JUnitTestDao], das die Implementierung JDBC testet;
- [spring-jpa-generic-JUnitTestDao-hibernate-eclipselink], das die Implementierungen JPA (Hibernate oder Eclipselink) testet (hier ist es EclipseLink)
Beide Ausführungen müssen erfolgreich sein.
9.2.6. Generierung der Tabellen mit Hibernate
Wir erstellen die Hibernate-Tabellen mit der folgenden Eclipse-Umgebung:
![]() |
Die Tabellen werden über die Ausführungskonfiguration mit dem Namen [generic-create-dbproduitscategories-hibernate] ohne Java-Agent generiert;
![]() | ![]() |
Das Skript SQL der von Hibernate generierten Datenbank lautet wie folgt:
SET FOREIGN_KEY_CHECKS=0;
USE `dbproduitscategories`;
CREATE TABLE `categories` (
`ID` BIGINT(20) NOT NULL AUTO_INCREMENT,
`NOM` VARCHAR(30) COLLATE utf8_general_ci NOT NULL,
`VERSIONING` BIGINT(20) DEFAULT NULL,
PRIMARY KEY (`ID`) USING BTREE,
UNIQUE KEY `UK_7ajcg7japnxw846ru01damg8s` (`NOM`) USING BTREE
) ENGINE=InnoDB
AUTO_INCREMENT=1 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'
;
CREATE TABLE `produits` (
`ID` BIGINT(20) NOT NULL AUTO_INCREMENT,
`DESCRIPTION` VARCHAR(100) COLLATE utf8_general_ci DEFAULT NULL,
`CATEGORIE_ID` BIGINT(20) NOT NULL,
`NOM` VARCHAR(30) COLLATE utf8_general_ci NOT NULL,
`PRIX` DOUBLE NOT NULL,
`VERSIONING` BIGINT(20) DEFAULT NULL,
PRIMARY KEY (`ID`) USING BTREE,
UNIQUE KEY `UK_hfvjn9lp7qoo5x79uu0ump3rf` (`NOM`) USING BTREE,
KEY `FK_p3foj9yrqnmi7856n9s8mbpue` (`CATEGORIE_ID`) USING BTREE,
CONSTRAINT `FK_p3foj9yrqnmi7856n9s8mbpue` FOREIGN KEY (`CATEGORIE_ID`) REFERENCES `categories` (`ID`)
) ENGINE=InnoDB
AUTO_INCREMENT=1 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'
;
CREATE TABLE `roles` (
...
) ENGINE=InnoDB
AUTO_INCREMENT=1 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'
;
CREATE TABLE `users` (
...
) ENGINE=InnoDB
AUTO_INCREMENT=1 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'
;
CREATE TABLE `users_roles` (
...
) ENGINE=InnoDB
AUTO_INCREMENT=1 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'
;
Die generierten Tabellen sind identisch, da auch Hibernate die Annotationen JPA verwendet hat. Für Hibernate habe ich kein Äquivalent zur Annotation EclipseLink [@OnCascadeDelete] gefunden, die dasAttribut SQL [ON DELTE CASCADE] für den Fremdschlüssel [PRODUITS.CATEGORIE_ID] (Zeile 25) erzeugt hat. Dieses Attribut muss daher manuell generiert werden, da es für die Tests erforderlich ist:
![]() |
![]() |
![]() |
Das Gleiche gilt für die beiden Fremdschlüssel der Tabelle [USERS_ROLES]:
![]() |
Schließlich müssen, wie bereits bei der Implementierung EclipseLink geschehen, die Spalten [VERSIONING] der fünf Tabellen einen Standardwert haben:
![]() |
Nachdem dies erledigt ist, überprüfen Sie, ob die folgenden Ausführungskonfigurationen erfolgreich sind:
- [spring-jdbc-generic-04.JUnitTestDao], das die Implementierung JDBC testet;
- [spring-jpa-generic-JUnitTestDao-hibernate-eclipselink], das die Implementierungen JPA (Hibernate oder Eclipselink – hier wird es Hibernate sein) testet
Beide Ausführungen müssen erfolgreich sein.
9.2.7. Generierung der Tabellen mit OpenJpa
Wir wiederholen den vorherigen Vorgang mit einer JPA- oder OpenJpa-Implementierung:
![]() |
Hinweis: Drücken Sie Alt-F5 und generieren Sie alle Maven-Projekte neu;
Wir ändern die Klasse [ConfigJpa], die das Projekt [mysql-config-jpa-openjpa] konfiguriert, wie folgt:
package generic.jpa.config;
import generic.jdbc.config.ConfigJdbc;
import java.util.Map;
import javax.persistence.EntityManagerFactory;
import org.apache.tomcat.jdbc.pool.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
@Configuration
@Import({ ConfigJdbc.class })
public class ConfigJpa {
// der Provider JPA
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
OpenJpaVendorAdapter openJpaVendorAdapter = new OpenJpaVendorAdapter();
openJpaVendorAdapter.setShowSql(false);
openJpaVendorAdapter.setDatabase(Database.MYSQL);
openJpaVendorAdapter.setGenerateDdl(true);
return openJpaVendorAdapter;
}
..
// EntityManagerFactory
@Bean
public EntityManagerFactory entityManagerFactory(JpaVendorAdapter jpaVendorAdapter, DataSource dataSource) {
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(jpaVendorAdapter);
factory.setPackagesToScan(ENTITIES_PACKAGES);
Map<String, Object> mapJpaProperties = factory.getJpaPropertyMap();
mapJpaProperties.put("openjpa.jdbc.MappingDefaults",
"ForeignKeyDeleteAction=cascade,JoinForeignKeyDeleteAction=restrict");
factory.setDataSource(dataSource);
factory.afterPropertiesSet();
return factory.getObject();
}
}
- Zeilen 40–41: Wir legen eine Eigenschaft für OpenJPA an, die angibt, wie Fremdschlüssel bei der Generierung der Tabellen erstellt werden sollen. Ohne diese Eigenschaft werden keine Fremdschlüssel generiert. Das Attribut [ForeignKeyDeleteAction=cascade] ermöglicht die Generierung des Attributs [ON DELETE CASCADE] für diese Fremdschlüssel;
Die Tabellengenerierung erfolgt über die Ausführungskonfiguration mit dem Namen [generic-create-dbproduitscategories-openjpa], die zwei Java-Agenten enthält;

- Der erste Java-Agent ist der Spring-Agent, der bereits bei EclipseLink verwendet wird;
- Der zweite Java-Agent wird von OpenJpa bereitgestellt;
Das Skript SQL der generierten Datenbank lautet dann wie folgt:
SET FOREIGN_KEY_CHECKS=0;
USE `dbproduitscategories`;
CREATE TABLE `categories` (
`ID` BIGINT(20) NOT NULL AUTO_INCREMENT,
`NOM` VARCHAR(30) COLLATE utf8_general_ci NOT NULL,
`VERSIONING` BIGINT(20) DEFAULT NULL,
PRIMARY KEY (`ID`) USING BTREE,
UNIQUE KEY `U_CTGORIS_NOM` (`NOM`) USING BTREE
) ENGINE=InnoDB
AUTO_INCREMENT=1 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'
;
CREATE TABLE `produits` (
`ID` BIGINT(20) NOT NULL AUTO_INCREMENT,
`DESCRIPTION` VARCHAR(100) COLLATE utf8_general_ci DEFAULT NULL,
`CATEGORIE_ID` BIGINT(20) DEFAULT NULL,
`NOM` VARCHAR(30) COLLATE utf8_general_ci NOT NULL,
`PRIX` DOUBLE NOT NULL,
`VERSIONING` BIGINT(20) DEFAULT NULL,
PRIMARY KEY (`ID`) USING BTREE,
UNIQUE KEY `U_PRODUTS_NOM` (`NOM`) USING BTREE,
KEY `CATEGORIE_ID` (`CATEGORIE_ID`) USING BTREE,
CONSTRAINT `produits_ibfk_1` FOREIGN KEY (`CATEGORIE_ID`) REFERENCES `categories` (`ID`) ON DELETE CASCADE
) ENGINE=InnoDB
AUTO_INCREMENT=1 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'
;
CREATE TABLE `roles` (
`ID` BIGINT(20) NOT NULL AUTO_INCREMENT,
`NAME` VARCHAR(30) COLLATE utf8_general_ci NOT NULL,
`VERSIONING` BIGINT(20) DEFAULT NULL,
PRIMARY KEY (`ID`) USING BTREE,
UNIQUE KEY `U_ROLES_NAME` (`NAME`) USING BTREE
) ENGINE=InnoDB
AUTO_INCREMENT=1 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'
;
CREATE TABLE `users` (
`ID` BIGINT(20) NOT NULL AUTO_INCREMENT,
`LOGIN` VARCHAR(30) COLLATE utf8_general_ci NOT NULL,
`NAME` VARCHAR(30) COLLATE utf8_general_ci NOT NULL,
`PASSWORD` VARCHAR(60) COLLATE utf8_general_ci NOT NULL,
`VERSIONING` BIGINT(20) DEFAULT NULL,
PRIMARY KEY (`ID`) USING BTREE,
UNIQUE KEY `U_USERS_LOGIN` (`LOGIN`) USING BTREE
) ENGINE=InnoDB
AUTO_INCREMENT=1 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'
;
CREATE TABLE `users_roles` (
`ID` BIGINT(20) NOT NULL AUTO_INCREMENT,
`VERSIONING` BIGINT(20) DEFAULT NULL,
`ROLE_ID` BIGINT(20) NOT NULL,
`USER_ID` BIGINT(20) NOT NULL,
PRIMARY KEY (`ID`) USING BTREE,
KEY `ROLE_ID` (`ROLE_ID`) USING BTREE,
KEY `USER_ID` (`USER_ID`) USING BTREE,
CONSTRAINT `users_roles_ibfk_2` FOREIGN KEY (`USER_ID`) REFERENCES `users` (`ID`) ON DELETE CASCADE,
CONSTRAINT `users_roles_ibfk_1` FOREIGN KEY (`ROLE_ID`) REFERENCES `roles` (`ID`) ON DELETE CASCADE
) ENGINE=InnoDB
AUTO_INCREMENT=1 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'
;
Es handelt sich um dasselbe wie bei EclipseLink. Es werden daher dieselben Korrekturen an den Tabellen vorgenommen. Überprüfen Sie anschließend, ob die folgenden Ausführungskonfigurationen erfolgreich sind:
- [spring-jdbc-generic-04.JUnitTestDao], das die Implementierung JDBC testet;
- [spring-jpa-generic-JUnitTestDao-openjpa], das die Implementierung JPA und OpenJpa testet;
Beide Ausführungen müssen erfolgreich sein.
9.3. Generierung der Datenbank [dbproduits]
Die Basis [dbproduits] wird von den Projekten [spring-jdbc-01 à 03] verwendet. Sie kann auch aus einer Entität JPA generiert werden.
![]() |
- in [1], den Eclipse-Projekten. Man befindet sich in einer Konfiguration MySQL / EclipseLink. Das Generierungsprojekt für die Datenbank [dbproduits] ist [generic-create-dbproduits];
- in [2] ist die zu generierende Tabelle [PRODUITS];
Hinweis: Drücken Sie Alt-F5 und generieren Sie alle Maven-Projekte neu;
9.3.1. Maven-Konfiguration
Die Maven-Konfiguration des Projekts [generic-create-dbproduits] lautet wie folgt:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>dvp.spring.database</groupId>
<artifactId>generic-create-dbproduits</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>generic-create-dbproduits</name>
<description>création de la bases de données [dbproduits] à l'aide des annotations JPA</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.3.RELEASE</version>
</parent>
<dependencies>
<!-- Konfiguration JPA des SGBD -->
<dependency>
<groupId>dvp.spring.database</groupId>
<artifactId>generic-config-jpa</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>spring.data.console.Main</start-class>
<java.version>1.7</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
</plugin>
</plugins>
</build>
</project>
Es gibt nur eine Abhängigkeit (Zeilen 22–26) zum Projekt, das die Schicht JPA konfiguriert. Letztendlich lauten die Abhängigkeiten wie folgt:
![]() |
9.3.2. Die Spring-Konfiguration
![]() |
Die Spring-Konfigurationsklasse lautet wie folgt:
package console;
import generic.jdbc.config.ConfigJdbc;
import generic.jpa.config.ConfigJpa;
import javax.persistence.EntityManagerFactory;
import org.apache.tomcat.jdbc.pool.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
@EnableJpaRepositories(basePackages = { "console" })
@Configuration
@Import({ ConfigJpa.class })
public class AppConfig {
// Datenquelle
@Bean
public DataSource dataSource() {
// Datenquelle TomcatJdbc
DataSource dataSource = new DataSource();
// Zugriffskonfiguration JDBC
dataSource.setDriverClassName(ConfigJdbc.DRIVER_CLASSNAME);
dataSource.setUsername(ConfigJdbc.USER_DBPRODUITS);
dataSource.setPassword(ConfigJdbc.PASSWD_DBPRODUITS);
dataSource.setUrl(ConfigJdbc.URL_DBPRODUITS);
// anfänglich offene Verbindungen
dataSource.setInitialSize(5);
// Ergebnis
return dataSource;
}
// EntityManagerFactory
@Bean
public EntityManagerFactory entityManagerFactory(JpaVendorAdapter jpaVendorAdapter, DataSource dataSource) {
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(jpaVendorAdapter);
factory.setPersistenceUnitName("generic-jpa-entities-dbproduits");
factory.setDataSource(dataSource);
factory.afterPropertiesSet();
return factory.getObject();
}
}
- Zeile 18: Die Beans der Klasse [ConfigJpa] (Abschnitt 7.3) werden importiert;
- Zeilen 22–35: Die Datenquelle [dataSource] wird neu definiert. In [ConfigJpa] ist die Datenquelle die Datenbank [dbproduitscategories]. Hier wird es die Datenbank [dbproduits] sein;
- Zeilen 38–46: Die Bean [entityManagerFactory] der Klasse [ConfigJpa] wird neu definiert. In dieser Klasse lauteten die Entitäten JPA ursprünglich [Produit, Categorie]. Hier ist es lediglich [Produit], und sie hat nicht dieselbe Definition wie in dem Projekt, das die Schicht JPA konfiguriert;
- Zeile 42: Um diese neue Entität JPA zu definieren, wird auf die Entitäten JPA verwiesen, die in der Datei [META-INF/persistence.xml] definiert sind:
![]() |
Die Datei [persistence.xml] lautet wie folgt:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" 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_1_0.xsd">
<persistence-unit name="generic-jpa-entities-dbproduits" transaction-type="RESOURCE_LOCAL">
<!-- Entitäten JPA -->
<class>generic.jpa.entities.dbproduits.Produit</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>
</persistence>
- Zeile 6: die einzige Entität JPA;
- Zeile 4: der Name der Persistenz-Einheit [generic-jpa-entities-dbproduits], auf die in der Bean [entityManagerFactory] verwiesen wird;
9.3.3. Die Entität JPA [Produit]
![]() |
Die Entität JPA ist im Projekt [mysql-config-jpa-eclipselink] wie folgt definiert:
package generic.jpa.entities.dbproduits;
import generic.jdbc.config.ConfigJdbc;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity(name="Produit1")
@Table(name = ConfigJdbc.TAB_PRODUITS)
public class Produit {
// Felder
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = ConfigJdbc.TAB_PRODUITS_ID)
private int id;
@Column(name = ConfigJdbc.TAB_PRODUITS_NOM, unique = true, length = 30, nullable = false)
private String nom;
@Column(name = ConfigJdbc.TAB_PRODUITS_CATEGORIE, nullable = false)
private int categorie;
@Column(name = ConfigJdbc.TAB_PRODUITS_PRIX, nullable = false)
private double prix;
@Column(name = ConfigJdbc.TAB_PRODUITS_DESCRIPTION, length = 100, nullable = false)
private String description;
// Konstruktoren
public Produit() {
}
public Produit(int id, String nom, int categorie, double prix, String description) {
this.id = id;
this.nom = nom;
this.categorie = categorie;
this.prix = prix;
this.description = description;
}
// Getter und Setter
...
}
Es handelt sich um eine mittlerweile klassische Definition von JPA. Es sei lediglich auf folgende Punkte hingewiesen:
- Zeile 12: Der Entität wurde der Name [Produit1] zugewiesen. Standardmäßig entspricht der Name einer Entität dem Namen der Klasse, in diesem Fall [Produit]. Da es jedoch im selben Projekt eine weitere Entität mit dem Namen JPA [Produit] gibt, wurde bereits vor der Ausführung ein Fehler gemeldet. Dieser wurde auf folgende Weise behoben:
- Zeile 24: Die Kategorie ist hier eine einfache Nummer;
- es bestehen keine Beziehungen zwischen den Entitäten. Wir haben es also mit einer sehr einfachen Situation zu tun;
9.3.4. Die ausführbare Klasse
![]() |
Die Klasse [CreateDatabase] sieht wie folgt aus:
package console;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class CreateDataBase {
public static void main(String[] args) {
// Es reicht aus, den Spring-Kontext zu instanziieren, um die Datenbanktabellen zu erstellen [dbproduits]
// Außerdem ist mindestens ein Spring Data Repository erforderlich, sonst passiert nichts
System.out.println("Travail en cours...");
new AnnotationConfigApplicationContext(AppConfig.class).close();
System.out.println("Travail terminé...");
}
}
Diesen Code haben wir bereits kennengelernt.
9.3.5. Generierung von EclipseLink
Die Tabelle [PRODUITS] wird mit folgender Ausführungskonfiguration angelegt:
![]() | ![]() |
Die Konsolenprotokolle lauten wie folgt:
Kehren wir nun zum Client [MyManager] zurück und aktualisieren wir die Ansicht [1-2]:
![]() |
In [3] ist zu sehen, dass eine Tabelle generiert wurde. Überprüfen wir nun die DDL (Domain Definition Language) der Datenbank:
SET FOREIGN_KEY_CHECKS=0;
USE `dbproduits`;
CREATE TABLE `produits` (
`ID` BIGINT(20) NOT NULL AUTO_INCREMENT,
`CATEGORIE` INTEGER(11) NOT NULL,
`DESCRIPTION` VARCHAR(100) COLLATE utf8_general_ci NOT NULL,
`NOM` VARCHAR(30) COLLATE utf8_general_ci NOT NULL,
`PRIX` DOUBLE NOT NULL,
PRIMARY KEY (`ID`) USING BTREE,
UNIQUE KEY `NOM` (`NOM`) USING BTREE
) ENGINE=InnoDB
AUTO_INCREMENT=1 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'
;
Wir erhalten tatsächlich die erwartete Tabelle. Um dies zu überprüfen, führen wir die folgende Konfiguration aus:
![]() | ![]() |
Sie muss erfolgreich sein.
9.3.6. Hibernate-Generierung
![]() | ![]() |
Hinweis: Drücken Sie Alt-F5 und generieren Sie alle Maven-Projekte neu;
Die Ausführungskonfiguration lautet wie folgt:
![]() | ![]() |
Das von Hibernate generierte Skript SQL lautet wie folgt:
USE `dbproduits`;
CREATE TABLE `produits` (
`ID` BIGINT(20) NOT NULL AUTO_INCREMENT,
`CATEGORIE` INTEGER(11) NOT NULL,
`DESCRIPTION` VARCHAR(100) COLLATE utf8_general_ci NOT NULL,
`NOM` VARCHAR(30) COLLATE utf8_general_ci NOT NULL,
`PRIX` DOUBLE NOT NULL,
PRIMARY KEY (`ID`) USING BTREE,
UNIQUE KEY `UK_hfvjn9lp7qoo5x79uu0ump3rf` (`NOM`) USING BTREE
) ENGINE=InnoDB
AUTO_INCREMENT=1 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'
;
9.3.7. Generierung von OpenJpa
![]() | ![]() |
Hinweis: Drücken Sie Alt-F5 und generieren Sie alle Maven-Projekte neu;
Die Ausführungskonfiguration lautet wie folgt:
![]() | ![]() |
Das von OpenJpa generierte Skript SQL lautet wie folgt:
USE `dbproduits`;
CREATE TABLE `produits` (
`ID` BIGINT(20) NOT NULL AUTO_INCREMENT,
`CATEGORIE` INTEGER(11) NOT NULL,
`DESCRIPTION` VARCHAR(100) COLLATE utf8_general_ci NOT NULL,
`NOM` VARCHAR(30) COLLATE utf8_general_ci NOT NULL,
`PRIX` DOUBLE NOT NULL,
PRIMARY KEY (`ID`) USING BTREE,
UNIQUE KEY `U_PRODUTS_NOM` (`NOM`) USING BTREE
) ENGINE=InnoDB
AUTO_INCREMENT=1 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'
;

















































