In hibernate 4 - spring 4 setup it was possible to generate DDL using SchemaExport
object:
LocalSessionFactoryBean sfb = (LocalSessionFactoryBean) context.getBean("&sessionFactory");
SchemaExport schema = new SchemaExport(sfb.getConfiguration());
But hibernate 5 replaces SchemaExport(Configuration configuration)
constructor with SchemaExport(MetadataImplementator metadataImplementator)
.
MetadataImplementator is not readily available on
org.springframework.orm.hibernate5.LocalSessionFactoryBean
or org.springframework.orm.hibernate5.LocalSessionFactoryBuilder
I hacked it like this:
MetadataSources metadataSources = (MetadataSources) FieldUtils.readField(configuration, "metadataSources", true);
Metadata metadata = metadataSources
.getMetadataBuilder(configuration.getStandardServiceRegistryBuilder().build())
.applyPhysicalNamingStrategy(new MyPhysicialNamingStrategy())
.applyImplicitNamingStrategy(ImplicitNamingStrategyJpaCompliantImpl.INSTANCE)
.build();
MetadataImplementor metadataImpl = (MetadataImplementor) metadata;
SchemaExport schema = new SchemaExport(metadataImplementor);
But it would be nice to have a better way and also, Validator annotations (@NotNull, @Size) are not used for DDL generation and I don't know if it is a bug in Hibernate 5 or this setup.
I am using hibernate 5.0.0.CR4 and spring 4.2.0.RELEASE
You need to implement org.hibernate.integrator.spi.Integrator
where you can store required data to some holder.
Work example you can find here https://github.com/valery-barysok/spring4-hibernate5-stackoverflow-34612019
register it as the service at META-INF/services/org.hibernate.integrator.spi.Integrator
file
public class Integrator implements org.hibernate.integrator.spi.Integrator {
@Override
public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
HibernateInfoHolder.setMetadata(metadata);
HibernateInfoHolder.setSessionFactory(sessionFactory);
HibernateInfoHolder.setServiceRegistry(serviceRegistry);
}
@Override
public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
}
}
Use it
new SchemaExport((MetadataImplementor) HibernateInfoHolder.getMetadata()).create(true, true);
new SchemaUpdate(HibernateInfoHolder.getServiceRegistry(), (MetadataImplementor) HibernateInfoHolder.getMetadata()).execute(true, true);
Additional info you can find here Programmatic SchemaExport / SchemaUpdate with Hibernate 5 and Spring 4
There is Configuration over Convention
principle for Java Persistence API but Validation API is intended for validation purpose only. Validation is not absolute you can put different validation rules on the same field.
if you have for example
@Size(max = 50)
@NotNull(groups = DefaultGroup.class)
@Null(groups = SecondGroup.class)
private String shortTitle;
then it is interpreted as
@Size(max = 50)
@NotNull(groups = DefaultGroup.class)
@Null(groups = SecondGroup.class)
@Column(length = 255, nullable = true)
private String shortTitle;
see more details here Why does Hibernate Tools hbm2ddl generation not take into account Bean Validation annotations?
For Hibernate 5.2.7 (in my case) I've wrote a method to export schema that is based on packages scan like:
static void exportSchema(
DataSource dataSource,
Class<? extends Dialect> dialect,
String... packagesToScan) {
StandardServiceRegistryBuilder registryBuilder = new StandardServiceRegistryBuilder()
.applySetting(DATASOURCE, dataSource)
.applySetting(DIALECT, dialect); // dialect could be omitted
MetadataSources metadataSources = new MetadataSources(registryBuilder.build());
PathMatchingResourcePatternResolver resourceLoader = new PathMatchingResourcePatternResolver();
new LocalSessionFactoryBuilder(null, resourceLoader, metadataSources)
.scanPackages(packagesToScan);
Metadata metadata = metadataSources.buildMetadata();
new SchemaExport()
.setFormat(true)
.create(EnumSet.of(STDOUT, DATABASE), metadata);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With