JPA több one-to-many kapcsolat Spring Boot és a EclipseLink esetén
Felhasznált technológiák: Spring Boot 4, Spring Data JPA, EclipseLink 5
Már írtam egy posztot, hogy mi van akkor, ha egy entitásnak több one-to-many kapcsolata van.
A Spring Boot alapesetben a Hibernate JPA providert használja. Azonban be lehet állítani az EclipseLinket is. Nézzük meg, ez hogy viselkedik.
A posthoz tartozó példaprogram letölthető a GitHub-ról.
Ehhez először a pom.xml-ben kell a Hibernate-et exlude-olni,
és az EclipseLinket felvenni.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>5.0.0</version>
</dependency>
Valamint kell egy configuration osztály is.
@Configuration
public class EclipseLinkJpaConfiguration extends JpaBaseConfiguration {
public EclipseLinkJpaConfiguration(DataSource dataSource, JpaProperties properties, ObjectProvider<JtaTransactionManager> jtaTransactionManager) {
super(dataSource, properties, jtaTransactionManager);
}
@Override
protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
return new EclipseLinkJpaVendorAdapter();
}
@Override
protected Map<String, Object> getVendorProperties(DataSource dataSource) {
return Map.of(
"eclipselink.logging.level.sql", org.eclipse.persistence.logging.SessionLog.FINE_LABEL
);
}
}
Azt nem sikerült megoldanom, hogy az EclipseLink sémagenerálása előbb fusson le,
mint az adatbeszúrás. Ezért létrehoztam egy schema.sql állományt, mely
létrehozza a táblákat.
Ezután a teszteset sikeresen lefut, ami azt jelenti, hogy az Eclipselink is újrahasznosítja a már persistence contextbe került objektumokat.
A kiadott SQL:
SELECT DISTINCT ... FROM {oj EMPLOYEE t1 LEFT OUTER JOIN PHONE t0 ON (t0.EMPLOYEE_ID = t1.ID)} WHERE (t1.ID = ?)
SELECT ... FROM ADDRESS WHERE (EMPLOYEE_ID = ?)
Érdemes összehasonlítani a Hibernate által kiadott SQL-ekkel:
select distinct ... from employee e1_0 left join phone p1_0 on e1_0.id=p1_0.employee_id where e1_0.id=?
select distinct ... from employee e1_0 left join address a1_0 on e1_0.id=a1_0.employee_id where e1_0.id=?
Látható, hogy a második lekérdezés esetén az EclipseLink már csak az ADDRESS táblát kérdezte le,
addig a Hibernate ugyanúgy join-olt az employee táblával.