9. Het genereren van databases op basis van de entiteiten JPA
Het is mogelijk om de tabellen van een database aan te maken op basis van de entiteiten JPA. Dat laten we nu zien. Het voordeel hiervan is dat we kunnen controleren of de database die is gegenereerd op basis van de entiteiten JPA inderdaad de gewenste database is.
9.1. Inrichten van de werkomgeving
We gaan eerst aan de slag met een implementatie van JPA, EclipseLink en [1].
![]() |
Vervolgens verwijderen we de tabellen uit de database MySQL [dbproduitscategories] met de client [MyManager] (zie paragraaf 23.5). We beginnen met het verwijderen van de tabellen die de vreemde sleutels [1-3] bevatten:
![]() |
Vervolgens gaan we verder met de drie overgebleven tabellen [4-6]:
![]() |
We doen hetzelfde met de tabel [dbproduits] die wordt gebruikt door de projecten [spring-jdbc-01 à 03]:
![]() | ![]() |
Daarnaast moeten de twee generatieprojecten voor de twee databases worden geïmporteerd:
![]() |
- in [1] importeert men het project [generic-create-dbproduits], dat te vinden is in [<exemples>/spring-database-generic/spring-jpa] en [2];
![]() |
- in [4] importeren we het project [generic-create-dbproduitscategories], dat te vinden is in [<exemples>/spring-database-generic/spring-jpa] en [5];
Opmerking: druk op Alt-F5 en genereer alle Maven-projecten opnieuw;
9.2. Genereren van de basis [dbproduitscategories]
![]() |
9.2.1. Maven-configuratie
Het bestand [pom.xml] van het project ziet er als volgt uit:
<?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>
- regels 22-26: de afhankelijkheid van het project [spring-jpa-generic] dat in paragraaf 6.4 is besproken;
- regels 28-32: de afhankelijkheid van een weaver die zal worden gebruikt om de entiteiten JPA van de implementaties EclipseLink en OpenJpa te verrijken. Deze afhankelijkheid is niet nodig in het bestand [pom.xml], maar de bijbehorende jar-bestand zal de gebruikte Java-agent zijn. Door de afhankelijkheid in het bestand [pom.xml] op te nemen, zorgen we ervoor dat het jar-bestand zeker beschikbaar is;
Uiteindelijk zijn de afhankelijkheden als volgt:
![]() |
9.2.2. Spring-configuratie
![]() |
De klasse [AppConfig] configureert het Spring-project:
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 {
}
- regel 10: de klasse haalt de beans op uit de klasse [ConfigJpa]. Ter herinnering: deze klasse werkt met de entiteiten JPA uit de database [dbproduitscategories] (zie paragraaf 6.3);
- regel 11: er wordt aangegeven dat het pakket [console] moet worden doorzocht om daar instanties van [CrudRepository] te vinden;
In de klasse [ConfigJpa] vinden we de volgende bean (varieert afhankelijk van de gebruikte implementatie JPA):
// de provider JPA
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
// Opmerking: de entiteiten JPA en de EclipseLink-configuratie staan in het bestand META-INF/persistence.xml
EclipseLinkJpaVendorAdapter eclipseLinkJpaVendorAdapter = new EclipseLinkJpaVendorAdapter();
eclipseLinkJpaVendorAdapter.setShowSql(false);
eclipseLinkJpaVendorAdapter.setDatabase(Database.MYSQL);
eclipseLinkJpaVendorAdapter.setGenerateDdl(true);
return eclipseLinkJpaVendorAdapter;
}
Regel 8 is hier van belang. Deze regel komt voor in alle gebruikte JPA-implementaties. Hierin staat dat als de tabellen die bij de entiteiten JPA horen niet bestaan, deze moeten worden aangemaakt. We zullen deze eigenschap gebruiken om de tabellen te genereren.
9.2.3. De repositories
![]() |
De interface [ProduitsRepository] ziet er als volgt uit:
package console;
import generic.jpa.entities.dbproduitscategories.Produit;
import org.springframework.data.repository.CrudRepository;
public interface ProduitsRepository extends CrudRepository<Produit, Long> {
}
Het is de instantiëring hiervan die de instantiëring van de laag JPA zal veroorzaken. Op regel 7 verwijst de interface namelijk naar de entiteit JPA [Produit], wat de instantiatie van de laag JPA afdwingt. We hadden elke willekeurige interface [CrudRepository] kunnen gebruiken die naar een van de entiteiten JPA verwijst. We zien namelijk dat, hoewel de [repository] alleen verwijst naar de entiteit JPA [Produit], wel degelijk alle tabellen van alle entiteiten JPA worden gegenereerd.
9.2.4. De uitvoerbare klasse
![]() |
De klasse [CreateDatabase] ziet er als volgt uit:
package console;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class CreateDataBase {
public static void main(String[] args) {
// Je hoeft alleen maar de Spring-context te initialiseren om de tabellen van de database [dbproduitscategories] aan te maken
// er is ook minstens één Spring Data Repository nodig, anders gebeurt er niets
System.out.println("Travail en cours...");
new AnnotationConfigApplicationContext(AppConfig.class).close();
System.out.println("Travail terminé...");
}
}
- regel 11: de Spring-context wordt geïnstantieerd om deze onmiddellijk weer te sluiten. In deze context bevindt zich de bean [ProduitsRepository] die verwijst naar de entiteit JPA [Produit]. Dit is voldoende om de laag JPA te instantiëren en daarmee de tabellen van de database [dbproduitscategories] te genereren.
9.2.5. Tabellen genereren met EclipseLink
We bevinden ons in de volgende configuratie:
![]() |
- de laag [JDBC] is geconfigureerd voor de database [dbproduitscategories] van MySQL;
- de laag [JPA] is geïmplementeerd met EclipseLink;
- de database [dbproduitscategories] bevat geen tabellen;
Opmerking: druk op Alt-F5 en genereer alle Maven-projecten opnieuw;
We gebruiken de volgende uitvoerconfiguratie:
![]() |
- in [1-2] is voor deze uitvoeringsconfiguratie een Java-agent vereist om de test te laten slagen. Afhankelijk van het geval heeft EclipseLink deze agent niet altijd nodig, maar in dit geval mislukt de uitvoering als deze ontbreekt. Deze agent is geen EclipseLink-agent, maar een Spring-agent. Deze wordt geleverd door de afhankelijkheid:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
<scope>runtime</scope>
</dependency>
opgenomen in het bestand [pom.xml] van het project. De agent is te vinden in [<m2-repo>/org/springframework/spring-instrument/4.1.6.RELEASE/spring-instrument-4.1.6.RELEASE.jar], waarbij <m2-repo> de lokale Maven-repository is;
De uitvoering levert het volgende resultaat op:
![]() |
In [3] zien we dat de tabellen zijn gegenereerd. Laten we nu de DDL (Domain Definition Language) van de database controleren:
![]() | ![]() |
![]() |
Het script SQL voor het genereren van de tabellen kan ook worden opgeslagen in een bestand met de naam [1].
![]() | ![]() ![]() |
Het gegenereerde script SQL is als volgt:
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'
;
Laten we bijvoorbeeld eens kijken naar het script SQL dat de tabel [PRODUITS] genereert (regels 15-29):
- regel 16: [ID] is de primaire sleutel (regel 23) met het attribuut [AUTO_INCREMENT] (regel 5). Dit komt overeen met de annotaties [@Id, @GeneratedValue(strategy = GenerationType.IDENTITY), @Column(name = ConfigJdbc.TAB_JPA_ID)] van het veld [id] van de entiteit JPA;
- regel 17: de definitie van de kolom [DESCRIPTION] komt overeen met de annotatie [@Column(name = ConfigJdbc.TAB_PRODUITS_DESCRIPTION, length = 100)] van het veld [description] van de entiteit JPA;
- regel 18: de kolom [CATEGORIE_ID] is een vreemde sleutel van de tabel [PRODUITS] op de kolom [CATEGORIES.ID] (regel 26). Bovendien heeft deze vreemde sleutel het attribuut [ON DELETE CASCADE]. Dit komt overeen met de annotaties [@ManyToOne(fetch = FetchType.LAZY), @JoinColumn(name = ConfigJdbc.TAB_PRODUITS_CATEGORIE_ID)] van het veld [Produit.categorie] en met de annotatie [@OneToMany(fetch = FetchType.LAZY, mappedBy = "categorie", cascade = { CascadeType.ALL }), @CascadeOnDelete] van het veld [Categorie.produits];
- regel 19: de definitie van de kolom [NOM] komt overeen met de annotatie [@Column(name = ConfigJdbc.TAB_PRODUITS_NOM, unique = true, length = 30, nullable = false)] van het veld [Produit.nom];
- regel 20: de definitie van kolom [PRIX] komt overeen met de annotatie [@Column(name = ConfigJdbc.TAB_PRODUITS_PRIX, nullable = false)] van het veld [Produit.prix];
- regels 24-25: het script maakt drie indexen aan voor elk van de unieke kolommen van de tabel;
De gegenereerde tabellen hebben geen standaardwaarde voor het veld VERSIONING, terwijl de Java-code verwacht dat er wel een is. Als deze standaardwaarde ontbreekt, slagen bepaalde tests niet. Dit attribuut wordt als volgt toegevoegd:
![]() |
![]() |
![]() |
Dit doen we voor de vijf tabellen die de kolom [VERSIONING] hebben. De waarde van de standaardwaarde doet er niet toe. Ze moet gewoon aanwezig zijn. Vervolgens wordt de waarde met 1 verhoogd bij elke wijziging van de rij waartoe ze behoort.
Controleer daarna of de volgende uitvoerconfiguraties slagen:
- [spring-jdbc-generic-04.JUnitTestDao], die de implementatie JDBC test;
- [spring-jpa-generic-JUnitTestDao-hibernate-eclipselink], die de implementaties JPA (Hibernate of Eclipselink) test (in dit geval is dat EclipseLink)
Beide uitvoeringen moeten slagen.
9.2.6. Tabellen genereren met Hibernate
We maken de Hibernate-tabellen aan met de volgende Eclipse-omgeving:
![]() |
Het genereren van de tabellen gebeurt via de uitvoeringsconfiguratie met de naam [generic-create-dbproduitscategories-hibernate] zonder Java-agent;
![]() | ![]() |
Het script SQL van de door Hibernate gegenereerde database is als volgt:
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'
;
De gegenereerde tabellen zijn identiek, aangezien Hibernate ook de annotaties JPA heeft gebruikt. Voor Hibernate heb ik geen equivalent gevonden voor de annotatie EclipseLink [@OnCascadeDelete] die hetattribuut SQL [ON DELTE CASCADE] op de vreemde sleutel [PRODUITS.CATEGORIE_ID] (regel 25) heeft gegenereerd. Dit attribuut moet dus handmatig worden gegenereerd, omdat het nodig is voor de tests:
![]() |
![]() |
![]() |
Hetzelfde moet worden gedaan met de twee vreemde sleutels van de tabel [USERS_ROLES]:
![]() |
Ten slotte moeten, net zoals bij de implementatie EclipseLink, de kolommen [VERSIONING] van de vijf tabellen een standaardwaarde hebben:
![]() |
Controleer vervolgens of de volgende uitvoeringsconfiguraties slagen:
- [spring-jdbc-generic-04.JUnitTestDao], die de implementatie JDBC test;
- [spring-jpa-generic-JUnitTestDao-hibernate-eclipselink], waarmee de implementaties JPA (Hibernate of Eclipselink; in dit geval is dat Hibernate) worden getest
Beide uitvoeringen moeten slagen.
9.2.7. Tabellen genereren met OpenJpa
We herhalen de vorige procedure met een implementatie van JPA OpenJpa:
![]() |
Opmerking: druk op Alt-F5 en genereer alle Maven-projecten opnieuw;
We passen de klasse [ConfigJpa] aan, die het project [mysql-config-jpa-openjpa] configureert, als volgt:
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 {
// de 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();
}
}
- regels 40-41: we maken een eigenschap aan voor OpenJPA die aangeeft hoe de vreemde sleutels moeten worden gegenereerd bij het genereren van de tabellen. Zonder deze eigenschap worden de vreemde sleutels niet gegenereerd. Met het attribuut [ForeignKeyDeleteAction=cascade] kan het attribuut [ON DELETE CASCADE] op deze vreemde sleutels worden gegenereerd;
Het genereren van de tabellen gebeurt via de uitvoeringsconfiguratie met de naam [generic-create-dbproduitscategories-openjpa], die twee Java-agenten bevat;

- de eerste Java-agent is de Spring-agent die al wordt gebruikt met EclipseLink;
- de tweede Java-agent wordt geleverd door OpenJpa;
Het script SQL van de gegenereerde database ziet er dan als volgt uit:
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'
;
Dit is hetzelfde als bij EclipseLink. We zullen dus dezelfde correcties aanbrengen in de tabellen. Controleer daarna of de volgende uitvoeringsconfiguraties slagen:
- [spring-jdbc-generic-04.JUnitTestDao], waarmee de implementatie JDBC wordt getest;
- [spring-jpa-generic-JUnitTestDao-openjpa], waarmee de implementaties JPA en OpenJpa worden getest;
Beide uitvoeringen moeten slagen.
9.3. Genereren van de basis [dbproduits]
De basis [dbproduits] wordt gebruikt door de projecten [spring-jdbc-01 à 03]. Deze kan ook worden gegenereerd op basis van een entiteit JPA.
![]() |
- in [1], de Eclipse-projecten. We bevinden ons dan in een configuratie MySQL / EclipseLink. Het generatieproject van de basis [dbproduits] is [generic-create-dbproduits];
- in [2] is de te genereren tabel [PRODUITS];
Opmerking: druk op Alt-F5 en genereer alle Maven-projecten opnieuw;
9.3.1. Maven-configuratie
De Maven-configuratie van het project [generic-create-dbproduits] is als volgt:
<?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>
<!-- configuratie JPA van 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>
Er is slechts één afhankelijkheid, regels 22-26, in het project dat de laag JPA configureert. Uiteindelijk zijn de afhankelijkheden als volgt:
![]() |
9.3.2. De Spring-configuratie
![]() |
De Spring-configuratieklasse is als volgt:
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 {
// gegevensbron
@Bean
public DataSource dataSource() {
// gegevensbron TomcatJdbc
DataSource dataSource = new DataSource();
// toegangscontrole JDBC
dataSource.setDriverClassName(ConfigJdbc.DRIVER_CLASSNAME);
dataSource.setUsername(ConfigJdbc.USER_DBPRODUITS);
dataSource.setPassword(ConfigJdbc.PASSWD_DBPRODUITS);
dataSource.setUrl(ConfigJdbc.URL_DBPRODUITS);
// aanvankelijk geopende verbindingen
dataSource.setInitialSize(5);
// resultaat
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();
}
}
- regel 18: de beans van de klasse [ConfigJpa] (paragraaf 7.3) worden geïmporteerd;
- regels 22-35: de gegevensbron [dataSource] wordt opnieuw gedefinieerd. In [ConfigJpa] is de gegevensbron de database [dbproduitscategories]. Hier zal dat de database [dbproduits] zijn;
- regels 38-46: de bean [entityManagerFactory] van de klasse [ConfigJpa] wordt opnieuw gedefinieerd. In deze klasse waren de entiteiten JPA en [Produit, Categorie]. Hier is het alleen [Produit] en deze heeft niet dezelfde definitie als in het project dat de laag JPA configureert;
- regel 42: om deze nieuwe entiteit JPA te definiëren, wordt verwezen naar de entiteiten JPA die zijn gedefinieerd in het bestand [META-INF/persistence.xml]:
![]() |
Het bestand [persistence.xml] ziet er als volgt uit:
<?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">
<!-- entiteiten JPA -->
<class>generic.jpa.entities.dbproduits.Produit</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>
</persistence>
- regel 6: de enige entiteit JPA;
- regel 4: de naam van de persistentie-eenheid [generic-jpa-entities-dbproduits] waarnaar wordt verwezen in de bean [entityManagerFactory];
9.3.3. De entiteit JPA [Produit]
![]() |
De entiteit JPA is in het project [mysql-config-jpa-eclipselink] als volgt gedefinieerd:
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 {
// velden
@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;
// constructors
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;
}
// getters en setters
...
}
Dit is een inmiddels klassieke definitie van JPA. We wijzen alleen op de volgende punten:
- regel 12: aan de entiteit is de naam [Produit1] gegeven. Standaard is de naam van een entiteit de naam van de klasse, in dit geval [Produit]. Maar omdat er in hetzelfde project nog een andere entiteit JPA [Produit] bestaat, werd er al vóór de uitvoering een fout gemeld. Deze fout is op deze manier verholpen;
- regel 24: de categorie is hier een eenvoudig nummer;
- er zijn geen relaties tussen entiteiten. We hebben dus te maken met een zeer eenvoudige situatie;
9.3.4. De uitvoerbare klasse
![]() |
De klasse [CreateDatabase] is als volgt:
package console;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class CreateDataBase {
public static void main(String[] args) {
// het volstaat om de Spring-context te instantiëren om de tabellen van de database aan te maken [dbproduits]
// er is ook minstens één Spring Data Repository nodig, anders gebeurt er niets
System.out.println("Travail en cours...");
new AnnotationConfigApplicationContext(AppConfig.class).close();
System.out.println("Travail terminé...");
}
}
Dit is een code die we al eerder zijn tegengekomen.
9.3.5. Generatie EclipseLink
De tabel [PRODUITS] wordt aangemaakt met de volgende uitvoeringsconfiguratie:
![]() | ![]() |
De logboeken van de console zijn als volgt:
Laten we nu teruggaan naar de client [MyManager] en de weergave [1-2] vernieuwen:
![]() |
In [3] zien we dat er een tabel is gegenereerd. Laten we nu de DDL (Domain Definition Language) van de database controleren:
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'
;
We krijgen inderdaad de verwachte tabel. Om dit te controleren, voeren we de volgende configuratie uit:
![]() | ![]() |
Dit moet slagen.
9.3.6. Hibernate-generatie
![]() | ![]() |
Opmerking: druk op Alt-F5 en genereer alle Maven-projecten opnieuw;
De uitvoerconfiguratie is als volgt:
![]() | ![]() |
Het door Hibernate gegenereerde script SQL is als volgt:
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. Generatie OpenJpa
![]() | ![]() |
Opmerking: druk op Alt-F5 en genereer alle Maven-projecten opnieuw;
De uitvoeringsconfiguratie is als volgt:
![]() | ![]() |
Het script SQL, gegenereerd door OpenJpa, is als volgt:
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'
;

















































