Hibernate Field Naming with Spring Boot

Issue: BAEL-2098
This commit is contained in:
Juan Moreno 2018-11-02 10:36:21 -03:00 committed by Josh Cummings
parent 18d7252bdf
commit 184d60ca6e
8 changed files with 280 additions and 0 deletions

View File

@ -0,0 +1,19 @@
package com.baeldung.naming;
import org.hibernate.jpa.boot.spi.IntegratorProvider;
import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
import java.util.Collections;
import java.util.Map;
/**
* Custom implementation of the {@link HibernatePropertiesCustomizer HibernatePropertiesCustomizer}.
* We can use it to set custom hibernate properties.
*/
public class HibernateConfig implements HibernatePropertiesCustomizer {
@Override
public void customize(Map<String, Object> hibernateProperties) {
hibernateProperties.put("hibernate.integrator_provider", (IntegratorProvider) () -> Collections.singletonList(MetadataExtractorIntegrator.INSTANCE));
}
}

View File

@ -0,0 +1,41 @@
package com.baeldung.naming;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.model.relational.Database;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.integrator.spi.Integrator;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
/**
* Custom implementation of the {@link Integrator Integrator} interface.
* We can use it to getting access to the binding metadata between entity mappings and database tables.
*/
public class MetadataExtractorIntegrator implements Integrator {
public static final MetadataExtractorIntegrator INSTANCE = new MetadataExtractorIntegrator();
private Database database;
private Metadata metadata;
public Database getDatabase() {
return database;
}
public Metadata getMetadata() {
return metadata;
}
@Override
public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
this.database = metadata.getDatabase();
this.metadata = metadata;
}
@Override
public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
}
}

View File

@ -0,0 +1,19 @@
package com.baeldung.naming.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import java.util.List;
@Entity
public class Account {
@Id private Long id;
private String defaultEmail;
@OneToMany List<Preference> preferences;
@Column(name = "\"Secondary_Email\"") private String secondaryEmail;
}

View File

@ -0,0 +1,16 @@
package com.baeldung.naming.entity;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
@Entity
public class Preference {
@Id private Long id;
private String name;
@ManyToOne private Account account;
}

View File

@ -0,0 +1,58 @@
package com.baeldung.naming;
import com.baeldung.naming.entity.Account;
import org.assertj.core.api.SoftAssertions;
import org.hibernate.boot.Metadata;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Table;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@DataJpaTest
@TestPropertySource(properties = {
"spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl",
"spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl"
})
public class LegacyJpaImplNamingIntegrationTest extends NamingConfig {
@Test
public void givenLegacyJpaImplNamingStrategy_whenCreateDatabase_thenGetStrategyNames() {
Metadata metadata = MetadataExtractorIntegrator.INSTANCE.getMetadata();
String entity = Account.class.getCanonicalName();
PersistentClass persistentClass = metadata.getEntityBinding(entity);
Table table = persistentClass.getTable();
String physicalNameExpected = "Secondary_Email";
String implicitNameExpected = "defaultEmail";
String tableNameExpected = "Account";
String tableNameCreated = table.getName();
boolean columnNameIsQuoted = table
.getColumn(3)
.isQuoted();
String physicalNameCreated = table
.getColumn(3)
.getName();
String implicitNameCreated = table
.getColumn(2)
.getName();
SoftAssertions.assertSoftly(softly -> {
softly
.assertThat(columnNameIsQuoted)
.isTrue();
softly
.assertThat(tableNameCreated)
.isEqualTo(tableNameExpected);
softly
.assertThat(physicalNameCreated)
.isEqualTo(physicalNameExpected);
softly
.assertThat(implicitNameCreated)
.isEqualTo(implicitNameExpected);
});
}
}

View File

@ -0,0 +1,15 @@
package com.baeldung.naming;
import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
public class NamingConfig {
@TestConfiguration
static class Config {
@Bean
public HibernatePropertiesCustomizer customizer() {
return new HibernateConfig();
}
}
}

View File

@ -0,0 +1,54 @@
package com.baeldung.naming;
import com.baeldung.naming.entity.Account;
import org.assertj.core.api.SoftAssertions;
import org.hibernate.boot.Metadata;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Table;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@DataJpaTest
@TestPropertySource(properties = {
"spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy",
"spring.jpa.hibernate.naming.implicit-strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy"
})
public class SpringBootDefaultNamingIntegrationTest extends NamingConfig {
@Test
public void givenDefaultBootNamingStrategy_whenCreateDatabase_thenGetStrategyNames() {
Metadata metadata = MetadataExtractorIntegrator.INSTANCE.getMetadata();
String entity = Account.class.getCanonicalName();
PersistentClass persistentClass = metadata.getEntityBinding(entity);
Table table = persistentClass.getTable();
String physicalNameExpected = "secondary_email";
String implicitNameExpected = "default_email";
String tableNameExpected = "account";
String tableNameCreated = table.getName();
String physicalNameCreated = table
.getColumn(3)
.getName();
String implicitNameCreated = table
.getColumn(2)
.getName();
SoftAssertions softly = new SoftAssertions();
softly
.assertThat(tableNameCreated)
.isEqualTo(tableNameExpected);
softly
.assertThat(physicalNameCreated)
.isEqualTo(physicalNameExpected);
softly
.assertThat(implicitNameCreated)
.isEqualTo(implicitNameExpected);
softly.assertAll();
}
}

View File

@ -0,0 +1,58 @@
package com.baeldung.naming;
import com.baeldung.naming.entity.Preference;
import org.assertj.core.api.SoftAssertions;
import org.hibernate.boot.Metadata;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Table;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Collection;
@RunWith(SpringRunner.class)
@DataJpaTest
@TestPropertySource(properties = {
"spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl",
"spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl",
})
public class StrategyLegacyHbmImplIntegrationTest extends NamingConfig {
@Test
public void givenLegacyHbmImplNamingNamingStrategy_whenCreateDatabase_thenGetStrategyNames() {
Metadata metadata = MetadataExtractorIntegrator.INSTANCE.getMetadata();
String entity = Preference.class.getCanonicalName();
PersistentClass persistentClass = metadata.getEntityBinding(entity);
Collection<Table> tables = metadata
.getDatabase()
.getDefaultNamespace()
.getTables();
Table preferenceTable = persistentClass.getTable();
String tableNameExpected = "Account_preferences";
Table accountPreferencesTable = tables
.stream()
.filter(table -> table
.getName()
.equals(tableNameExpected))
.findFirst()
.get();
String implicitNameExpected = "account";
String implicitNameCreated = preferenceTable
.getColumn(3)
.getName();
String tableNameCreated = accountPreferencesTable.getName();
SoftAssertions.assertSoftly(softly -> {
softly
.assertThat(implicitNameCreated)
.isEqualTo(implicitNameExpected);
softly
.assertThat(tableNameCreated)
.isEqualTo(tableNameExpected);
});
}
}