I have tried to set up a gradle task that runs a java main class that is intended to generate a SQL schema.
I have no persistence.xml configuration file.
Here is my configuration and code:
My gradle task:
task JpaSchemaExport(type: JavaExec){
description "Exports Jpa schema"
dependsOn compileJava
main = "com.bignibou.tools.jpa.JpaSchemaExport"
classpath = sourceSets.main.runtimeClasspath + configurations.compile
}
My export utility:
public class JpaSchemaExport {
public static void main(String[] args) throws IOException {
// execute(args[0], args[1]);
execute("default", "build/schema.sql");
System.exit(0);
}
public static void execute(String persistenceUnitName, String destination) {
final Properties persistenceProperties = new Properties();
// XXX force persistence properties : remove database target
persistenceProperties.setProperty(org.hibernate.cfg.AvailableSettings.HBM2DDL_AUTO, "");
persistenceProperties.setProperty(AvailableSettings.SCHEMA_GEN_DATABASE_ACTION, "none");
// XXX force persistence properties : define create script target from metadata to destination
// persistenceProperties.setProperty(AvailableSettings.SCHEMA_GEN_CREATE_SCHEMAS, "true");
persistenceProperties.setProperty(AvailableSettings.SCHEMA_GEN_SCRIPTS_ACTION, "create");
persistenceProperties.setProperty(AvailableSettings.SCHEMA_GEN_CREATE_SOURCE, "metadata");
persistenceProperties.setProperty(AvailableSettings.SCHEMA_GEN_SCRIPTS_CREATE_TARGET, destination);
Persistence.generateSchema(persistenceUnitName, persistenceProperties);
}
}
My data configuration:
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setPackagesToScan("com.bignibou.domain");
emf.setDataSource(dataSource);
emf.setPersistenceProvider(new HibernatePersistenceProvider());
emf.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
emf.setJpaPropertyMap(propertiesMap());
return emf;
}
private Map<String, String> propertiesMap() {
Map<String, String> propertiesMap = new HashMap<>();
propertiesMap.put("hibernate.dialect", hibernateDialect);
propertiesMap.put("hibernate.hbm2ddl.auto", hibernateHbm2ddlAuto);
propertiesMap.put("hibernate.ejb.naming_strategy", hibernateEjbNamingStrategy);
propertiesMap.put("hibernate.connection.charSet", hibernateConnectionCharset);
propertiesMap.put("hibernate.show_sql", hibernateLogSqlInfo);
propertiesMap.put("hibernate.format_sql", hibernateLogSqlInfo);
propertiesMap.put("hibernate.use_sql_comments", hibernateLogSqlInfo);
propertiesMap.put("hibernate.generate_statistics", hibernateGenerateStatistics);
propertiesMap.put("hibernate.cache.use_second_level_cache", hibernateCacheUseSecondLevelCache);
propertiesMap.put("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory");
propertiesMap.put("javax.persistence.sharedCache.mode", "ENABLE_SELECTIVE");
return propertiesMap;
}
Here is the exception I get:
Exception in thread "main" javax.persistence.PersistenceException: No persistence provider found for schema generation for persistence-unit named default
at javax.persistence.Persistence.generateSchema(Persistence.java:93)
at com.bignibou.tools.jpa.JpaSchemaExport.execute(JpaSchemaExport.java:31)
at com.bignibou.tools.jpa.JpaSchemaExport.main(JpaSchemaExport.java:14)
edit: I do get warnings indeed:
:bignibou-server:JpaSchemaExport
2015-05-16 14:46:44,423 [main] WARN org.hibernate.ejb.HibernatePersistence - HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider [org.hibernate.ejb.HibernatePersistence]; use [org.hibernate.jpa.HibernatePersistenceProvider] instead.
2015-05-16 14:46:44,423 [main] WARN org.hibernate.ejb.HibernatePersistence - HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider [org.hibernate.ejb.HibernatePersistence]; use [org.hibernate.jpa.HibernatePersistenceProvider] instead.
2015-05-16 14:46:44,423 [main] WARN org.hibernate.ejb.HibernatePersistence - HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider [org.hibernate.ejb.HibernatePersistence]; use [org.hibernate.jpa.HibernatePersistenceProvider] instead.
Exception in thread "main" javax.persistence.PersistenceException: No persistence provider found for schema generation for persistence-unit named default
at javax.persistence.Persistence.generateSchema(Persistence.java:93)
at com.bignibou.tools.jpa.JpaSchemaExport.execute(JpaSchemaExport.java:32)
at com.bignibou.tools.jpa.JpaSchemaExport.main(JpaSchemaExport.java:14)
:bignibou-server:JpaSchemaExport FAILED
Generating schema with Spring Boot app:
Your
JpaSchemaExport
is not executed within a Spring Context as far as I can see from your code.When you run your
JpaSchemaExport
from Gradle or command line you create your ownEntityManager
which has nothing to do with Spring and looks for apersistence.xml
file in theMETA-INF
directory. For Spring Boot Applications this file is not needed and thus may not exist.When I run something which looks similar your JpaSchemaExport the output is something like
A Spring Boot Commandline Application (one that has a Spring Context) looks something like:
i.e. your
JpaSchemaExport
may be rewritten asAs an alternative you can create a
META-INF/persistence.xml
which can be used by your Spring Boot application as well as by yourJpaSchemaExport
.It seems that
Persistence.generateSchema()
usesPersistenceProviderResolverHolder
which holds aPersistenceProviderResolver
to get a list of all availablePersistenceProvider
s. Maybe you should try implementing your ownPersistenceProviderResolver
(only 2 methods) to return the one you want to use (org.hibernate.jpa.HibernatePersistenceProvider
) before callingPersistence.generateSchema()
.Your code is very good and clean. Is there any other warning on server startup like log4j properties missing .. etc.,
I think the problem is related to some missing jar or classpath entry, though not sure about it.
You would need to set an explicit name for the persistence unit that is created programmatically using the following method and then make sure to call the afterPropertiesSet() method:
Refer to your persistence unit using this name instead of "default"