Hibernate exception when try to launch Tomcat - spring

I have application on spring-mvc+jpa. I build war and try to start on tomcat.
DataConfig:
import org.hibernate.ejb.HibernatePersistence;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.annotation.Resource;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;
#Configuration
#EnableTransactionManagement
#PropertySource("classpath:app.properties")
public class DataConfig {
private static final String PROP_DATABASE_DRIVER = "db.driver";
private static final String PROP_DATABASE_URL = "db.url";
private static final String PROP_DATABASE_USERNAME = "db.username";
private static final String PROP_HIBERNATE_DIALECT = "db.hibernate.dialect";
private static final String PROP_HIBERNATE_SHOW_SQL = "db.hibernate.show_sql";
private static final String PROP_ENTITYMANAGER_PACKAGES_TO_SCAN = "db.entitymanager.packages.to.scan";
private static final String PROP_HIBERNATE_HBM2DDL_AUTO = "db.hibernate.hbm2ddl.auto";
#Resource
private Environment env;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty(PROP_DATABASE_DRIVER));
dataSource.setUrl(env.getRequiredProperty(PROP_DATABASE_URL));
dataSource.setUsername(env.getRequiredProperty(PROP_DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty("db.password"));
return dataSource;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean();
entityManager.setDataSource(dataSource());
entityManager.setPackagesToScan(env.getRequiredProperty(PROP_ENTITYMANAGER_PACKAGES_TO_SCAN));
entityManager.setPersistenceProviderClass(HibernatePersistence.class);
entityManager.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
entityManager.setJpaProperties(getHibernateProperties());
return entityManager;
}
#Bean
public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
private Properties getHibernateProperties() {
Properties properties = new Properties();
properties.put(PROP_HIBERNATE_DIALECT, env.getRequiredProperty(PROP_HIBERNATE_DIALECT));
properties.put(PROP_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROP_HIBERNATE_SHOW_SQL));
properties.put(PROP_HIBERNATE_HBM2DDL_AUTO, env.getRequiredProperty(PROP_HIBERNATE_HBM2DDL_AUTO));
return properties;
}
}
app.properties is:
#DB properties:
db.driver=com.mysql.cj.jdbc.Driver
db.url=jdbc:mysql://127.0.0.1:3306/mydb
db.username=root
db.password=111111
#Hibernate Configuration:
db.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
db.hibernate.show_sql=true
db.entitymanager.packages.to.scan=ru.sbrf.risks.services.data.model
db.hibernate.hbm2ddl.auto = create-drop
So, there is error message in tomcat logs:
Caused by: javax.persistence.PersistenceException: [PersistenceUnit:
default] Unable to build EntityManagerFactory at
org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:924)
at
org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:899)
at
org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:76)
at
org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:287)
at
org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
... 57 more Caused by: org.hibernate.HibernateException: Connection
cannot be null when 'hibernate.dialect' not set at
org.hibernate.service.jdbc.dialect.internal.DialectFactoryImpl.determineDialect(DialectFactoryImpl.java:97)
at
org.hibernate.service.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:67)
at
org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:170)
at
org.hibernate.service.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:75)
at
org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:159)
at
org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:131)
at
org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1818)
at
org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1776)
at
org.hibernate.ejb.EntityManagerFactoryImpl.(EntityManagerFactoryImpl.java:96)
at
org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:914)
... 63 more

Hibernate doesn't understand the properties you are passing it. You have hibernate.dialect defined as db.hibernate.dialect Remove the db portion and just have it as hibernate.dialect and do the same with your other hibernate related properties.
https://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/session-configuration.html

#PropertySource("classpath:app.properties")
This annotation value replace with below passing value
#PropertySource(value = {"classpath:application.properties","file:config/application.properties"}, ignoreResourceNotFound = true)
and rebuild you project.now it's working fine.

Related

NoSuchMethodError Table.indexes() hibernate-core-5.2.13.Final.jar when try to start application?

There is application srping+jpa. Webserver is Websphere 8.5.13
So, I launch application by using WebApplicationInitializer where I add configs.
There is problem when added PersisnteceConfig:
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.annotation.Resource;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;
#Configuration
#EnableTransactionManagement
#EnableJpaAuditing
#EnableJpaRepositories(basePackages = {"persistence"})
#PropertySource("classpath:application.properties")
#ComponentScan(basePackages = {"persistence"})
public class PersistenceConfig {
private static final String PROP_DATABASE_DRIVER = "db.driver";
private static final String PROP_DATABASE_URL = "db.url";
private static final String PROP_DATABASE_USERNAME = "db.username";
private static final String PROP_DATABASE_PASSWORD = "db.password";
private static final String PROP_HIBERNATE_DIALECT = "db.hibernate.dialect";
private static final String PROP_HIBERNATE_SHOW_SQL = "db.hibernate.show_sql";
private static final String PACKAGE_WITH_JPA_ENTITIES = "ru.sbrf.risks.services.data.persistence";
private static final String PROP_HIBERNATE_HBM2DDL_AUTO = "db.hibernate.hbm2ddl.auto";
private static final String DO_NOT_AUDIT_LOCKING_FIELD = "org.hibernate.envers.do_not_audit_optimistic_locking_field";
#Resource
private Environment env;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty(PROP_DATABASE_DRIVER));
dataSource.setUrl(env.getRequiredProperty(PROP_DATABASE_URL));
dataSource.setUsername(env.getRequiredProperty(PROP_DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty(PROP_DATABASE_PASSWORD));
return dataSource;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
System.out.println("1");
LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean();
System.out.println("2");
entityManager.setDataSource(dataSource());
System.out.println("3");
entityManager.setPackagesToScan(PACKAGE_WITH_JPA_ENTITIES);
System.out.println("4");
entityManager.setPersistenceProviderClass(HibernatePersistenceProvider.class);
System.out.println("5");
entityManager.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
System.out.println("6");
entityManager.setJpaProperties(getHibernateProperties());
System.out.println("7");
return entityManager;
}
#Bean
public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
//Set properties hibernate
private Properties getHibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", env.getRequiredProperty(PROP_HIBERNATE_DIALECT));
properties.put("hibernate.show_sql", env.getRequiredProperty(PROP_HIBERNATE_SHOW_SQL));
properties.put("hibernate.hbm2ddl.auto", env.getRequiredProperty(PROP_HIBERNATE_HBM2DDL_AUTO));
properties.put("org.hibernate.envers.do_not_audit_optimistic_locking_field",
env.getRequiredProperty(DO_NOT_AUDIT_LOCKING_FIELD));
properties.put("verifyServerCertificate", false);
properties.put("useSSL", false);
properties.put("requireSSL", false);
properties.put("useLegacyDatetimeCode", false);
properties.put("useUnicode", "yes");
properties.put("characterEncoding", "UTF-8");
properties.put("serverTimezone", "UTC");
properties.put("useJDBCCompliantTimezoneShift", true);
return properties;
}
}
So,I use hibernate-core-5.2.13.Final libriary and when try to launch application on WebSphere 8.5.13, I have an error message:
Invocation of init method failed; nested exception is
java.lang.NoSuchMethodError:
javax/persistence/Table.indexes()[Ljavax/persistence/Index; (loaded
from
file:/opt/IBM/WebSphere/AppServer/plugins/javax.j2ee.persistence.jar
by org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader#ec08ccb6)
called from class org.hibernate.cfg.annotations.EntityBinder (loaded
from
file:/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/installedApps/MyApp_war.ear/MyApp.war/WEB-INF/lib/hibernate-core-5.2.13.Final.jar
by
com.ibm.ws.classloader.CompoundClassLoader#7f080f2e[war:MyApp_war/MyApp.war]
You're attempting to use a version of Hibernate that implements a different spec version than the JPA 2.0 included in WebSphere 8.5.5. That can be done, but you'll need to bring your own version of the JPA API as well. To do that, you'll either need to switch your web module's class loader to "Parent Last" or move Hibernate and the JPA API jar(s) to a shared library and configure the library to use an isolated class loader (which effectively sets "Parent Last" just for the jars in the library).

How to support multiple databases engines on Spring?

I’m building a Spring Boot application that should support various databases engines (MySQL, PostgreSQL, Oracle, SQL Server).
The user will be prompted to select which database it would like to use when installing the application and all tables will be created after this. I think that I should save the user option somewhere and then use it to select the right engine that my application will use to instantiate the repositories.
I googled for some references or best practices that I should follow to implement this but wasn’t able to find (maybe I’m searching the wrong terms - sorry).
Do you have any resource that points me to the right direction?
Thanks a lot!!!
You can refer sample. In sample I use hibernate + spring boot for multiple databases.
You can work by this way:
Step 1: you declare in application.properties info connect of database (mysql, oracle, postgresql)
# MySQL-Database
mysql.db.driver: com.mysql.jdbc.Driver
mysql.db.url: jdbc:mysql://localhost:3306/test
mysql.db.username: root
mysql.db.password: root
mysql.hibernate.dialect: org.hibernate.dialect.MySQL5Dialect
mysql.entitymanager.packagesToScan: com.test.mysql
# postgresql-Database
postgresql.db.driver: org.postgresql.Driver
postgresql.db.url: jdbc:postgresql://localhost:5432/postgres_demo
postgresql.db.username: root
postgresql.db.password:
postgresql.hibernate.dialect: org.hibernate.dialect.PostgreSQLDialect
postgresql.entitymanager.packagesToScan: com.test.postgresql
# Oracle-Database
oracle.db.driver: oracle.jdbc.driver.OracleDriver
oracle.db.url: jdbc:oracle:thin:#localhost:1521:xe
oracle.db.username: root
oracle.db.password:
oracle.hibernate.dialect: org.hibernate.dialect.Oracle10gDialect
oracle.entitymanager.packagesToScan: com.test.oracle
Step 2: In project spring boot you can refer structure project such as:
Step 3 : Implement data source for mysql, oracle, postgresql. you can refer MysqlDatabaseConfig.java, OracleDatabaseConfig.java, PostgresDatabaseConfig.java
package com.test.mysql;
import java.util.Properties;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableTransactionManagement
public class MysqlDatabaseConfig {
#Value("${mysql.db.driver}")
private String DB_DRIVER;
#Value("${mysql.db.password}")
private String DB_PASSWORD;
#Value("${mysql.db.url}")
private String DB_URL;
#Value("${mysql.db.username}")
private String DB_USERNAME;
#Value("${mysql.hibernate.dialect}")
private String HIBERNATE_DIALECT;
#Value("${mysql.entitymanager.packagesToScan}")
private String ENTITYMANAGER_PACKAGES_TO_SCAN;
#Bean(name="mysqlDataSource")
#Primary
public DataSource cmrDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(DB_DRIVER);
dataSource.setUrl(DB_URL);
dataSource.setUsername(DB_USERNAME);
dataSource.setPassword(DB_PASSWORD);
return dataSource;
}
#Bean(name="mysqlSessionFactory")
public LocalSessionFactoryBean crmSessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(cmrDataSource());
sessionFactoryBean.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);
Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.dialect", HIBERNATE_DIALECT);
sessionFactoryBean.setHibernateProperties(hibernateProperties);
return sessionFactoryBean;
}
#Bean(name="mysqlTransactionManager")
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(crmSessionFactory().getObject());
return transactionManager;
}
}
OracleDatabaseConfig.java
package com.test.oracle;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.Properties;
#Configuration
#EnableTransactionManagement
public class OracleDatabaseConfig {
#Value("${oracle.db.driver}")
private String DB_DRIVER;
#Value("${oracle.db.password}")
private String DB_PASSWORD;
#Value("${oracle.db.url}")
private String DB_URL;
#Value("${oracle.db.username}")
private String DB_USERNAME;
#Value("${oracle.hibernate.dialect}")
private String HIBERNATE_DIALECT;
#Value("${oracle.entitymanager.packagesToScan}")
private String ENTITYMANAGER_PACKAGES_TO_SCAN;
#Bean(name="oracleDataSource")
#Primary
public DataSource cmrDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(DB_DRIVER);
dataSource.setUrl(DB_URL);
dataSource.setUsername(DB_USERNAME);
dataSource.setPassword(DB_PASSWORD);
return dataSource;
}
#Bean(name="oracleSessionFactory")
public LocalSessionFactoryBean crmSessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(cmrDataSource());
sessionFactoryBean.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);
Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.dialect", HIBERNATE_DIALECT);
sessionFactoryBean.setHibernateProperties(hibernateProperties);
return sessionFactoryBean;
}
#Bean(name="oracleTransactionManager")
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(crmSessionFactory().getObject());
return transactionManager;
}
}
PostgresDatabaseConfig.java
package com.test.postgresql;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.Properties;
#Configuration
#EnableTransactionManagement
public class PostgresDatabaseConfig {
#Value("${postgresql.db.driver}")
private String DB_DRIVER;
#Value("${postgresql.db.password}")
private String DB_PASSWORD;
#Value("${postgresql.db.url}")
private String DB_URL;
#Value("${postgresql.db.username}")
private String DB_USERNAME;
#Value("${postgresql.hibernate.dialect}")
private String HIBERNATE_DIALECT;
#Value("${postgresql.entitymanager.packagesToScan}")
private String ENTITYMANAGER_PACKAGES_TO_SCAN;
#Bean(name="postgresqlDataSource")
#Primary
public DataSource cmrDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(DB_DRIVER);
dataSource.setUrl(DB_URL);
dataSource.setUsername(DB_USERNAME);
dataSource.setPassword(DB_PASSWORD);
return dataSource;
}
#Bean(name="postgresqlSessionFactory")
public LocalSessionFactoryBean crmSessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(cmrDataSource());
sessionFactoryBean.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);
Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.dialect", HIBERNATE_DIALECT);
sessionFactoryBean.setHibernateProperties(hibernateProperties);
return sessionFactoryBean;
}
#Bean(name="postgresqlTransactionManager")
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(crmSessionFactory().getObject());
return transactionManager;
}
}
Step 4: call to use:
in case mysql
package com.test.mysql.dao;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
#Repository
#Transactional("mysqlTransactionManager")
public class TestMysqlDao {
#Autowired
#Qualifier("mysqlSessionFactory")
private SessionFactory sessionFactory;
}
In case oracle
package com.test.oracle.dao;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
#Repository
#Transactional("oracleTransactionManager")
public class TestOracleDao {
#Autowired
#Qualifier("oracleSessionFactory")
private SessionFactory sessionFactory;
}
In case postgresql
package com.test.postgresql.dao;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
#Repository
#Transactional("postgresqlTransactionManager")
public class TestPostgresDao {
#Autowired
#Qualifier("postgresqlSessionFactory")
private SessionFactory sessionFactory;
}
It's unclear what you mean by installing but if you want your application to start with different databases you can use different Spring profiles with your application.yml Spring boot profiles
---
spring:
profiles: postgres
datasource:
url:
username:
password:
driver-class-name: org.postgresql.Driver
---
spring:
profiles: mysql
datasource:
url:
username:
password:
driver-class-name: com.mysql.jdbc.Driver
You can then start the application with the respective profile
java -jar -Dspring.profiles.active=mysql yourapp.jar
You can define different connections and get them with specific methods
private DataSource mySqlDataSource;
private DataSource postgresDataSource;
public Connection getMySqlConnection() throws SQLException {
mySqlDataSource.getConnection();
}
public Connection getPostgresConnection() throws SQLException {
postgresDataSource.getConnection();
}

ERROR 11664 --- [main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000231: Schema export unsuccessful

I'm trying to get a small project of mine working, regarding the implementation of a process via WebServices.
Problem is: I dont even get to that point because I seem to hit trouble when booting Spring.
Spring is in fact booting but I cant get hibernate working ( atleast I think the problem lies with hibernate? ).
My ErrorLog: onPasteBin
My application.properties:
#New
spring.jpa.database-platform = org.hibernate.dialect.MySQL5Dialect
spring.jpa.show-sql = true
# Hibernate
spring.jpa.hibernate.ddl-auto=create
#Old
# Thymeleaf
spring.thymeleaf.cache: false
# Database
db.driver: com.mysql.jdbc.Driver
db.url: jdbc:mysql://127.0.0.1:3306/igt
db.username: root
db.password: passwort
# Hibernate
hibernate.dialect: org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql: true
hibernate.hbm2ddl.auto: create
entitymanager.packagesToScan: com.entities
And my DatabaseConfig.java:
package com.configs;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.Properties;
#Configuration
#EnableTransactionManagement
public class DatabaseConfig {
#Value("${db.driver}")
private String DB_DRIVER;
#Value("${db.password}")
private String DB_PASSWORD;
#Value("${db.url}")
private String DB_URL;
#Value("${db.username}")
private String DB_USERNAME;
#Value("${hibernate.dialect}")
private String HIBERNATE_DIALECT;
#Value("${hibernate.show_sql}")
private String HIBERNATE_SHOW_SQL;
#Value("${hibernate.hbm2ddl.auto}")
private String HIBERNATE_HBM2DDL_AUTO;
#Value("${entitymanager.packagesToScan}")
private String ENTITYMANAGER_PACKAGES_TO_SCAN;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(DB_DRIVER);
dataSource.setUrl(DB_URL);
dataSource.setUsername(DB_USERNAME);
dataSource.setPassword(DB_PASSWORD);
return dataSource;
}
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);
Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.dialect", HIBERNATE_DIALECT);
hibernateProperties.put("hibernate.show_sql", HIBERNATE_SHOW_SQL);
hibernateProperties.put("hibernate.hbm2ddl.auto", HIBERNATE_HBM2DDL_AUTO);
sessionFactoryBean.setHibernateProperties(hibernateProperties);
return sessionFactoryBean;
}
#Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager =
new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
}
I dont think the Application.java is really relevant to this, but here it is nonetheless:
package com;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Maybe the Project Structure is helpful:
Screenshot of the ProjectStructure
Thanks very much in advance =)

Using joda time with JPA/hibernate and spring

I would to persist to db creation date and time. I have some experience with date and time classes but I dont like them.
Recently I've started to use Joda time. I have to say that library is the best to work with date and time.
For now I would like to persist DateTime object from joda.
I've tried already:
#Type(type="org.joda.time.contrib.hibernate.PersistentDateTime")
private DateTime creationDate;
But it unfortunatelly dosnt work. Here is stack trace:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class com.derp.common.init.WebAppConfig: Invocation of init method failed; nested exception is org.hibernate.MappingException: Could not determine type for: org.joda.time.contrib.hibernate.PersistentDateTime
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1568)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:540)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1081)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1006)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:904)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:527)
... 41 more
Caused by: org.hibernate.MappingException: Could not determine type for: org.joda.time.contrib.hibernate.PersistentDateTime
at org.hibernate.cfg.annotations.SimpleValueBinder.fillSimpleValue(SimpleValueBinder.java:510)
at org.hibernate.cfg.SetSimpleValueTypeSecondPass.doSecondPass(SetSimpleValueTypeSecondPass.java:42)
at org.hibernate.cfg.Configuration.processSecondPassesOfType(Configuration.java:1472)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1420)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1846)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1930)
at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:372)
at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:453)
at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:438)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1627)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1564)
... 51 more
Caused by: org.hibernate.annotations.common.reflection.ClassLoadingException: Unable to load Class [org.joda.time.contrib.hibernate.PersistentDateTime]
at org.hibernate.annotations.common.util.StandardClassLoaderDelegateImpl.classForName(StandardClassLoaderDelegateImpl.java:60)
at org.hibernate.cfg.annotations.SimpleValueBinder.fillSimpleValue(SimpleValueBinder.java:491)
... 61 more
Caused by: java.lang.ClassNotFoundException: org.joda.time.contrib.hibernate.PersistentDateTime
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1324)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1177)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:344)
at org.hibernate.annotations.common.util.StandardClassLoaderDelegateImpl.classForName(StandardClassLoaderDelegateImpl.java:57)
... 62 more
And my fragment of pom.xml:
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.5</version>
</dependency>
I hope some one will help me.
----Edited------
WebMvcConfigurerAdapter
package com.derp.common.init;
import java.util.Properties;
import javax.annotation.Resource;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.http.MediaType;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
//import com.derp.common.wicketView.HomePage;
#Configuration
#ComponentScan("com.derp")
#EnableWebMvc
#EnableTransactionManagement
#PropertySource("classpath:application.properties")
public class WebAppConfig extends WebMvcConfigurerAdapter {
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_SERVICES = "services.entitymanager.packages.to.scan";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_COMMON = "common.entitymanager.packages.to.scan";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_CMS = "cms.entitymanager.packages.to.scan";
#Resource
private Environment env;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
return dataSource;
}
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
//sessionFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
sessionFactoryBean.setPackagesToScan(new String[] {
env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_SERVICES),
env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_COMMON),
env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_CMS)
});
sessionFactoryBean.setHibernateProperties(hibProperties());
return sessionFactoryBean;
}
private Properties hibProperties() {
Properties properties = new Properties();
properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
properties.put(PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO));
return properties;
}
#Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
// Simple strategy: only path extension is taken into account
configurer.favorPathExtension(true).
ignoreAcceptHeader(true).
useJaf(false).
defaultContentType(MediaType.TEXT_HTML).
mediaType("html", MediaType.TEXT_HTML).
mediaType("xml", MediaType.APPLICATION_XML).
mediaType("json", MediaType.APPLICATION_JSON);
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/img/**").addResourceLocations("/WEB-INF/img/*");
registry.addResourceHandler("/css/**").addResourceLocations("/WEB-INF/css/*");
registry.addResourceHandler("/js/**").addResourceLocations("/WEB-INF/js/*");
registry.addResourceHandler("/lib/**").addResourceLocations("/WEB-INF/lib/*");
}
}
WebApplicationInitializer class:
package com.derp.common.init;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.DispatcherServlet;
public class Initializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(WebAppConfig.class);
ctx.register(ThymeleafConfig.class);
servletContext.addListener(new ContextLoaderListener(ctx));
ctx.setServletContext(servletContext);
Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
servlet.addMapping("/");
servlet.setAsyncSupported(true);
servlet.setLoadOnStartup(1);
// Allow to use Put and Delete method for REST architecture
registerHiddenFieldFilter(servletContext);
}
private void registerHiddenFieldFilter(ServletContext aContext) {
aContext.addFilter("hiddenHttpMethodFilter", new HiddenHttpMethodFilter()).addMappingForUrlPatterns(null ,true, "/*");
}
}
You can use Jadira for this purpose:
Add this to your pom.xml:
<dependency>
<groupId>org.jadira.usertype</groupId>
<artifactId>usertype.extended</artifactId>
<version>3.2.0.GA</version>
</dependency>
And put this in your hibernate properties (hibProperties method in your config class):
properties.put("jadira.usertype.autoRegisterUserTypes", "true");
After you do this you can remove the #Type annotations from your Joda properties and it should work just fine (works for me both for Joda and JSR-310).

Spring 4 + Hibernate 4: ClassCastException with LocalSessionFactoryBean and SessionFactory

By mean of Spring libraries I have to develope a DAL (Data Access Layer) in the form of a jar library which will be imported into the main application.
I want to use Hibernate to access a MySQL DB and DBCP for the management of the connections pool.
I have written the config file DALConfig.java which contains the configuration of the DAL beans:
package my.dal.config;
import java.util.Properties;
import javax.annotation.Resource;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
// Needed by Spring to add this class to the ApplicationContext's configuration
#Configuration
#ComponentScan(basePackages = { "my.dal.config" })
// Property file in which are written the MySQL connection properties
#PropertySource("classpath:dbconnection.properties")
public class DALConfig {
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_POOL_INITIAL_SIZE = "pool.initialsize";
private static final String PROPERTY_NAME_POOL_MAX_IDLE = "pool.maxidle";
// Needed to access property file
#Resource
private Environment environment;
// The bean which defines the BasicDataSource (DBCP)
#Bean
public BasicDataSource dataSource() throws Exception
{
Properties props = new Properties();
props.put("driverClassName", environment.getProperty(PROPERTY_NAME_DATABASE_DRIVER));
props.put("url", environment.getProperty(PROPERTY_NAME_DATABASE_URL));
props.put("username", environment.getProperty(PROPERTY_NAME_DATABASE_USERNAME));
props.put("password", environment.getProperty(PROPERTY_NAME_DATABASE_PASSWORD));
props.put("initialSize", environment.getProperty(PROPERTY_NAME_POOL_INITIAL_SIZE));
props.put("maxIdle", environment.getProperty(PROPERTY_NAME_POOL_MAX_IDLE));
BasicDataSource bds = BasicDataSourceFactory.createDataSource(props);
return bds;
}
// Bean used to translate Hibernate's exceptions into Spring's ones
#Bean
public PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor()
{
PersistenceExceptionTranslationPostProcessor b = new PersistenceExceptionTranslationPostProcessor();
return b;
}
}
Then I wrote the HibernateConfig.java config file which contains the Hibernate configuration stuff
package my.dal.hibernateconfig;
import java.util.Properties;
import javax.annotation.Resource;
import javax.sql.DataSource;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
#Configuration
#ComponentScan(basePackages = { "my.dal.hibernatesessionfactory" })
#PropertySource("classpath:dbconnection.properties")
public class HibernateConfig {
private static final String PROPERTY_NAME_DAL_CLASSES_PACKAGE = "hibernate.dal.package";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
#Resource
private Environment environment;
#Autowired
DataSource dataSource;
// Bean which defines the FactoryBean for the SessionBean
#Bean
public LocalSessionFactoryBean sessionFactory()
{
LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean();
lsfb.setPackagesToScan(PROPERTY_NAME_DAL_CLASSES_PACKAGE);
Properties hibernateProperties = new Properties();
hibernateProperties.put("dialect", PROPERTY_NAME_HIBERNATE_DIALECT);
lsfb.setHibernateProperties(hibernateProperties);
lsfb.setDataSource(dataSource);
return lsfb;
}
#Bean
public HibernateTransactionManager transactionManager()
{
// THE EXCEPTION IS THROWN AT THIS LINE
HibernateTransactionManager htm = new HibernateTransactionManager((SessionFactory) sessionFactory());
return htm;
}
}
Next I wrote the UserDAO.java class which is a DAO for the User class which models the DB's User table.
package my.dal.dao;
import my.models.User;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
#Component
#Repository
#Transactional
public class UserDAO
{
private SessionFactory sessionFactory;
#Autowired
public UserDAO(SessionFactory sessionFactory) {
this.sessionFactory=sessionFactory;
}
public int insert(User user) {
return (Integer) sessionFactory.getCurrentSession().save(user);
}
public User getByUsername(String username) {
return (User) sessionFactory.getCurrentSession().get(User.class, username);
}
public void update(User user) {
sessionFactory.getCurrentSession().merge(user); // .update(user);
}
public void delete(String username) {
User u = getByUsername(username);
sessionFactory.getCurrentSession().delete(u);
}
}
The mapping class User.java (generated using the Eclipse's Hibernate tools) is
package my.models;
public class User implements java.io.Serializable {
private String username;
private String idUserKeystone;
private String firstName;
private String lastName;
private String password;
private String email;
private String emailRef;
private String employer;
private boolean confirmed;
// Getters, setters and full constructor
}
Now I want to test the DAL. The testing class is DALTest.java
package my.dal.tests;
import static org.junit.Assert.assertTrue;
import my.dal.config.DALConfig;
import my.dal.dao.UserDAO;
import my.dal.hibernateconfig.HibernateConfig;
import my.models.User;
import org.hibernate.SessionFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
#ContextConfiguration(classes = { DALConfig.class, HibernateConfig.class})
#RunWith(SpringJUnit4ClassRunner.class)
public class DALTest {
#Autowired
UserDAO userDAO;
#Test
public void testGetUser() {
User user = null;
// Let's see if the user "myuser" is into the database
user = userDAO.getByUsername("myuser");
assertTrue(null != user);
}
}
When I run the test it throws the following exceptions
java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class my.dal.hibernateconfig.HibernateConfig: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.orm.hibernate4.HibernateTransactionManager my.dal.hibernateconfig.HibernateConfig.transactionManager()] threw exception; nested exception is java.lang.ClassCastException: org.springframework.orm.hibernate4.LocalSessionFactoryBean$$EnhancerBySpringCGLIB$$d866ed45 cannot be cast to org.hibernate.SessionFactory
...
Caused by: java.lang.ClassCastException: org.springframework.orm.hibernate4.LocalSessionFactoryBean$$EnhancerBySpringCGLIB$$d866ed45 cannot be cast to org.hibernate.SessionFactory
at my.dal.hibernateconfig.HibernateConfig.transactionManager(HibernateConfig.java:55)
at my.dal.hibernateconfig.HibernateConfig$$EnhancerBySpringCGLIB$$bd53a036.CGLIB$transactionManager$1(<generated>)
at my.dal.hibernateconfig.HibernateConfig$$EnhancerBySpringCGLIB$$bd53a036$$FastClassBySpringCGLIB$$119f2c5b.invoke(<generated>)
...
It seems like the problem is the cast at the line
HibernateTransactionManager htm = new HibernateTransactionManager((SessionFactory) sessionFactory())
On the contrary, the Internet is full of example writing that line that way.
What could be the problem?
Thank you in advance
A FactoryBean<Foo> is a bean that creates objects of type Foo. It's not, itself, of type Foo (as the javadoc would show you). To get the Foo it creates, you simply call getObject() on the factory bean:
HibernateTransactionManager htm =
new HibernateTransactionManager(sessionFactory().getObject());

Resources