A followup question to my previous question: Generate an SQL DB creation script with Hibernate 4
The goal is to have a command line tool able to generate a file with the SQL schema of a given persistence unit (similarly to the hibernatetool-hbm2ddl Ant task present in the Hibernate Tools).
This, as per the answer to my previous question, can be achieved with org.hibernate.tool.hbm2ddl.SchemaExport
.
Instead of adding all the entities to the Configuration
(as suggested in the previous answer) I would like to specify a PersistenceUnit
.
Is it possible to add a persistence unit to an Hibernate Configuration
?
Something like
Properties properties = new Properties();
properties.put( "hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect" );
...
EntityManagerFactory entityManagerFactory =
Persistence.createEntityManagerFactory( "persistentUnitName", properties );
Configuration configuration = new Configuration();
... missing part ...
SchemaExport schemaExport = new SchemaExport( configuration );
schemaExport.setOutputFile( "schema.sql" );
...
Edit as requested in the comments a sample persistence.xml
. Each class is annotated with @Entity
<persistence
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"
version="1.0"
>
<persistence-unit
name="doiPersistenceUnit"
transaction-type="JTA"
>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/doi</jta-data-source>
<class>ch.ethz.id.wai.doi.bo.Doi</class>
[...]
<class>ch.ethz.id.wai.doi.bo.DoiPool</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.connection.characterEncoding" value="utf8" />
<property name="hibernate.connection.charSet" value="utf8" />
</properties>
</persistence-unit>
</persistence>
Well, if your classes are mapped via xml mappings (hbm
s) - you can add the documnets or jar files that include the xmls straight to the Configuration
instance using config.addJar(myJarFile)
and config.add(myXmlFile)
.
However, if you want your annotated classes to be scanned - I know of no such straightforward option through Hibernate (addPackage
adds metadata and not classes).
You may implement your own scan logic and add all annotated classes with config.addAnnotatedClass(myAnnotatedClass)
(or perhaps do it per specific packages you know for containing you ORM classes and thus maybe save some time).
UPDATE 2
Oh, even better, you can just iterate the persistence unit's ManagedType
s via getManagedTypes()
:
EntityManagerFactory entityManagerFactory =
Persistence.createEntityManagerFactory( unitName, config.getProperties() );
final Set<ManagedType<?>> managedTypes =
entityManagerFactory.getMetamodel().getManagedTypes();
for ( ManagedType<?> managedType : managedTypes ) {
final Class<?> javaType = managedType.getJavaType();
config.addAnnotatedClass( javaType );
}
UPDATE
You can determine the PersistenceUnit
of each Entity
- without parsing the xml - by checking against the relevant EntityManagerFactory
:
Class aClass = ... // get the class from your scanning
EntityManagerFactory entityManagerFactory =
Persistence.createEntityManagerFactory( unitName, config.getProperties() );
ManagedType<?> managedType = null;
try {
managedType = entityManagerFactory.getMetamodel().managedType( aClass );
} catch ( IllegalArgumentException e ) {
// happens when aClass isn't a type managed by the persistence unit
}
if ( managedType != null ) {
config.addAnnotatedClass( aClass );
}
Make sure to use different Configuration
instances for each persistence unit. Otherwise, annotated classes would just accumulate and so also the DDL.
I tried it and it worked great - printed two distinct DDLs for two different persistence units.
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