hibernatejpagradlehibernate-tools

PersistenceException: No persistence provider found for schema generation for persistence-unit named default


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 

Solution

  • 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 own EntityManager which has nothing to do with Spring and looks for a persistence.xml file in the META-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

    [main] INFO  o.h.j.b.i.PersistenceXmlParser - HHH000318: Could not find any META-INF/persistence.xml file in the class path
    [main] DEBUG o.h.jpa.HibernatePersistenceProvider - Located and parsed 0  persistence units; checking each 
    [main] DEBUG o.h.jpa.HibernatePersistenceProvider - Found no matching persistence units 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.example.springboot.jpa.JpaSchemaExport.execute(JpaSchemaExport.java:42)
        at
    com.example.springboot.jpa.JpaSchemaExport.main(JpaSchemaExport.java:14)
    

    A Spring Boot Commandline Application (one that has a Spring Context) looks something like:

    @SpringBootApplication
    public class Application implements CommandLineRunner {
    
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class);
        }
    
        @Override
        public void run(String... strings) throws Exception {
    
        }
    
    }
    

    i.e. your JpaSchemaExport may be rewritten as

    @SpringBootApplication
    public class JpaSchemaExport implements CommandLineRunner {
    
    
        public static void main(String[] args) {
            // maybe activate a special spring profile to enable 
            // "hibernate.hbm2ddl.auto", validate | update | create | create-drop
            // AvailableSettings.SCHEMA_GEN_DATABASE_ACTION, "none" 
            // AvailableSettings.SCHEMA_GEN_CREATE_SCHEMAS, "true"
            // AvailableSettings.SCHEMA_GEN_SCRIPTS_ACTION, "create"
            // AvailableSettings.SCHEMA_GEN_CREATE_SOURCE, "metadata"
            // AvailableSettings.SCHEMA_GEN_SCRIPTS_CREATE_TARGET, destination
    
            SpringApplication.run(JpaSchemaExport.class);
        }
    
        @Override
        public void run(String... strings) throws Exception {
           // nothing needed here 
        }
    
    }
    

    As an alternative you can create a META-INF/persistence.xml which can be used by your Spring Boot application as well as by your JpaSchemaExport.