I'm working on a new app (to me) and I received the no bean 'entityManagerFactory' available error on startup. Other people who've had this suggest it would not occur had I properly defined the data source. What confuses me is that either Spring Boot/JPA or Flyway (which I'm also using) insists on specific property names being used for your one data source. I'm not sure how someone would handle it if you had more than one. I need to change our application.properties file to fetch from environment variables so they can fetch the values from a secret. I have one definition so that flyway can do it's possible migrations. I have another so that Spring-Boot can do it's JPA based work. I have another because the existing code previously defined a dataSource and gets wired in accordingly. All are going to the same database. I wish I could use only one collection of application.properties properties, but more importantly, I want this entityManagerFactory error resolved. Because my fixes feel like a kludge, I wanted to reach out and see what I'm not understanding.
Here's the application.properties
spring.profiles.active=sprint-vault-services-not-available
spring.application.name=file-generator
file.generator.schema=FILE_GENERATOR
spring.flyway.enabled=true
spring.flyway.locations=classpath:db/migration
spring.flyway.schemas=${file.generator.schema}
spring.flyway.baseline-on-migrate=false
file-generator.date-format=MMddyy
file-generator.time-format=HHmmss
file-generator.ebcdic-output-path=app/output/ebcdic
file-generator.csv-output-path=app/output/csv
file-generator.header-timestamp-format=yyyyMMddHHmmss
file-generator.file-sequence-number=1
logging.path=app/logs
bcupload_datasource_url=${BCUPLOAD_DATASOURCE_URL}
#spring.jpa.properties.hibernate.default_schema=FILE_GENERATOR
bcupload_datasource_username=${BCUPLOAD_DATASOURCE_USERNAME}
bcupload_datasource_password=${BCUPLOAD_DATASOURCE_PASSWORD}
bcupload_datasource_driver=${BCUPLOAD_DATASOURCE_DRIVER}
bcupload_datasource_flyway_db_name=LocalFileGenerator
spring.datasource.driver-class-name=${BCUPLOAD_DATASOURCE_DRIVER}
spring.datasource.url=${BCUPLOAD_DATASOURCE_URL}
spring.datasource.password=${BCUPLOAD_DATASOURCE_PASSWORD}
spring.datasource.username=${BCUPLOAD_DATASOURCE_USERNAME}
spring.jpa.database-platform=DB2Platform
spring.jpa.show-sql=true
spring.jpa.generate-ddl=false
spring.jpa.hibernate.ddl-auto=none
spring.flyway.url= ${BCUPLOAD_DATASOURCE_URL}
spring.flyway.user=${BCUPLOAD_DATASOURCE_USERNAME}
spring.flyway.password=${BCUPLOAD_DATASOURCE_PASSWORD}
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
2021-04-12 23:06:34 DEBUG o.s.b.d.LoggingFailureAnalysisReporter - Application failed to start due to an exception
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:814)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1282)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:297)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:330)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:113)
at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:691)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:508)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:374)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:134)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1699)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1444)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:623)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:611)
at org.springframework.data.repository.config.DeferredRepositoryInitializationListener.onApplicationEvent(DeferredRepositoryInitializationListener.java:51)
at org.springframework.data.repository.config.DeferredRepositoryInitializationListener.onApplicationEvent(DeferredRepositoryInitializationListener.java:36)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:403)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:360)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:897)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:553)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
at com.mycompany.cloud.cost.ssc.file.generator.FileGeneratorApplication.main(FileGeneratorApplication.java:22)
Bean definition of datasource:
package com.ibm.cio.cloud.cost.ssc.file.generator.configuration;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
#Configuration
public class DataSourceConfig {
private String dataSourceUrl;
private String userName;
private String password;
private String driver;
/*
#Bean
public EntityManagerFactoryBuilder builder(Environment environment) {
Map<String, String> jpaProperties = new HashMap<>();
jpaProperties.put("hibernate.show_sql", environment.getProperty("spring.jpa.show-sql"));
jpaProperties.put("hibernate.format_sql", environment.getProperty("spring.jpa.properties.hibernate.format_sql"));
jpaProperties.put("hibernate.dialect", environment.getProperty("spring.jpa.properties.hibernate.dialect"));
return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), jpaProperties, null);
}
*/
#Autowired
public DataSourceConfig(#Value("${bcupload_datasource_url}") String bcupload_datasource_url,
#Value("${bcupload_datasource_username}") String bcupload_datasource_username,
#Value("${bcupload_datasource_password}") String bcupload_datasource_password,
#Value("${bcupload_datasource_driver}") String bcupload_datasource_driver) {
this.dataSourceUrl = bcupload_datasource_url;
this.userName = bcupload_datasource_username;
this.password = bcupload_datasource_password;
this.driver = bcupload_datasource_driver;
}
#Bean(name = "bcUploadDataSource")
public DataSource dataSource() {
return DataSourceBuilder.create()
.url(dataSourceUrl)
.username(userName)
.password(password)
.driverClassName(driver).build();
}
}
I have a project with several datasources and each datasource end up looking something like this:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy;
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
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.PlatformTransactionManager;
import javax.sql.DataSource;
import java.util.HashMap;
#Configuration
#EnableJpaRepositories(
basePackages = {"com.your.repositories.packages"},
entityManagerFactoryRef = "entityManagerFactory",
transactionManagerRef = "transactionManager")
public class DataSourceConfig{
#Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManager() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "com.entity.pacakges"});
em.setPersistenceUnitName("your_name");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto", env.getProperty("spring.jpa.hibernate.ddl-auto"));
properties.put("hibernate.dialect", env.getProperty("spring.jpa.properties.hibernate.dialect"));
properties.put("hibernate.show-sql", env.getProperty("spring.jpa.show-sql"));
properties.put("hibernate.temp.use_jdbc_metadata_defaults",
env.getProperty("spring.jpa.use_jdbc_metadata_defaults." + NAME));
properties.put("hibernate.physical_naming_strategy", SpringPhysicalNamingStrategy.class.getName());
properties.put("hibernate.implicit_naming_strategy", SpringImplicitNamingStrategy.class.getName());
em.setJpaPropertyMap(properties);
return em;
}
#Bean(name = "dataSource")
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));
dataSource.setPassword(env.getProperty("spring.datasource.password"));
return dataSource;
}
#Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManager().getObject());
return transactionManager;
}
}
So for your error, probably try to use LocalContainerEntityManagerFactoryBean instead of EntityManagerFactoryBuilder
Related
I have this issue. along 3 days.
When I tried to build the app with maven, i have this isues, but my build was successful, then when I deployed on WebLogic and I call any endpoint this response to me a 500 internal server error.
2021-10-29 17:23:47.788 INFO 64993 --- [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.4.32.Final
2021-10-29 17:23:48.021 INFO 64993 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2021-10-29 17:23:48.269 WARN 64993 --- [ main] o.h.e.j.e.i.JdbcEnvironmentInitiator : HHH000342: Could not obtain connection to query metadata
java.sql.SQLException: No suitable driver found for jdbc/facturador
at java.sql.DriverManager.getConnection(DriverManager.java:689) ~[na:1.8.0_202]
at java.sql.DriverManager.getConnection(DriverManager.java:208) ~[na:1.8.0_202]
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriverManager(DriverManagerDataSource.java:155) ~[spring-jdbc-5.3.10.jar:5.3.10]
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriver(DriverManagerDataSource.java:146) ~[spring-jdbc-5.3.10.jar:5.3.10]
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnectionFromDriver(AbstractDriverBasedDataSource.java:205) ~[spring-jdbc-5.3.10.jar:5.3.10]
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnection(AbstractDriverBasedDataSource.java:169) ~[spring-jdbc-5.3.10.jar:5.3.10]
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:180) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:68) [hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35) [hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101) [hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263) [hibernate-core-5.4.32.Final.jar:5.4.32.Final] (....)
and
2021-10-29 17:23:48.479 INFO 64993 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2021-10-29 17:23:48.501 INFO 64993 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2021-10-29 17:23:48.507 WARN 64993 --- [ main] o.h.e.j.e.i.JdbcEnvironmentInitiator : HHH000342: Could not obtain connection to query metadata
java.sql.SQLException: No suitable driver found for jdbc/differenceload
at java.sql.DriverManager.getConnection(DriverManager.java:689) ~[na:1.8.0_202]
at java.sql.DriverManager.getConnection(DriverManager.java:208) ~[na:1.8.0_202]
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriverManager(DriverManagerDataSource.java:155) ~[spring-jdbc-5.3.10.jar:5.3.10]
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriver(DriverManagerDataSource.java:146) ~[spring-jdbc-5.3.10.jar:5.3.10]
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnectionFromDriver(AbstractDriverBasedDataSource.java:205) ~[spring-jdbc-5.3.10.jar:5.3.10]
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnection(AbstractDriverBasedDataSource.java:169) ~[spring-jdbc-5.3.10.jar:5.3.10]
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:180) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:68) [hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35) [hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101) [hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263) [hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237) [hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214) [hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152) [hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286) [hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243) [hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214) [hibernate-core-5.4.32.Final.jar:5.4.32.Final]
There is my DataSourceConfig
import javax.sql.DataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
#Configuration
public class DataSourceConfig {
#Bean(name = "primaryDataSource",destroyMethod = "")
#Primary
#ConfigurationProperties("spring.datasource.primary")
public DataSource firstDataSource(){
return DataSourceBuilder.create().build();
}
#Bean(name = "secondaryDataSource",destroyMethod = "")
#ConfigurationProperties("spring.datasource.secondary")
public DataSource secondDataSource(){
return DataSourceBuilder.create().build();
}
}
Persistence for one DB
import java.util.HashMap;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
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.PlatformTransactionManager;
#Configuration
#PropertySource("classpath:/application.properties")
#EnableJpaRepositories(basePackages = "com.gt.tigo.diferenceLoad.entities.facturador", entityManagerFactoryRef = "localEntityManager", transactionManagerRef = "localTransactionManager")
public class PersistenceLocalConfig {
#Autowired
private Environment env;
#Bean
#Primary
public LocalContainerEntityManagerFactoryBean localEntityManager() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(localDataSource());
em.setPackagesToScan(new String[] { "com.gt.tigo.diferenceLoad.entities.local" });
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
#Primary
#Bean
public DataSource localDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl(env.getProperty("spring.datasource.primary.jndi-name"));
return dataSource;
}
#Primary
#Bean
public PlatformTransactionManager localTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(localEntityManager().getObject());
return transactionManager;
}
}
Persistence for other DB
import java.util.HashMap;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.PlatformTransactionManager;
#Configuration
#PropertySource("classpath:/application.properties")
#EnableJpaRepositories(basePackages = "com.gt.tigo.diferenceLoad.entities.facturador", entityManagerFactoryRef = "FacturadorEntityManager", transactionManagerRef = "facturadorTransactionManager")
public class PersistenceFacturadorConfig {
#Autowired
private Environment env;
#Bean
public LocalContainerEntityManagerFactoryBean FacturadorEntityManager() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(facturadorDataSource());
em.setPackagesToScan(new String[] { "com.gt.tigo.diferenceLoad.entities.facturador" });
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
#Bean
public DataSource facturadorDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl(env.getProperty("spring.datasource.secondary.jndi-name"));
return dataSource;
}
#Bean
public PlatformTransactionManager facturadorTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(FacturadorEntityManager().getObject());
return transactionManager;
}
}
Here it's my weblogic JNDI.
webLogic jndi
I tried all things.. but can't solve. please I need some help. Thanks!
#Base de datos LOCAL
spring.datasource.primary.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.primary.jndi-name=jdbc/differenceload
#Base de datos FACTURADOR
spring.datasource.secondary.jndi-name=jdbc/facturador
spring.datasource.secondary.driver-class-name=oracle.jdbc.OracleDriver
Quick look and make some changes in your file.
application.properties
spring.datasource.primary.jndi-name=java:/comp/env/jdbc/SecurityDS
spring.datasource.primary.driver-class-name=org.postgresql.Driver
spring.datasource.secondary.jndi-name=java:/comp/env/jdbc/TmsDS
spring.datasource.secondary.driver-class-name=org.postgresql.Driver
Configuration:
#Configuration
#EnableConfigurationProperties
public class AppConfig {
#Bean #ConfigurationProperties(prefix = "spring.datasource.primary")
public JndiPropertyHolder primary() {
return new JndiPropertyHolder();
}
#Bean #Primary
public DataSource primaryDataSource() {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
DataSource dataSource = dataSourceLookup.getDataSource(primary().getJndiName());
return dataSource;
}
#Bean# ConfigurationProperties(prefix = "spring.datasource.secondary")
public JndiPropertyHolder secondary() {
return new JndiPropertyHolder();
}
#Bean
public DataSource secondaryDataSource() {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
DataSource dataSource = dataSourceLookup.getDataSource(secondary().getJndiName());
return dataSource;
}
private static class JndiPropertyHolder {
private String jndiName;
public String getJndiName() {
return jndiName;
}
public void setJndiName(String jndiName) {
this.jndiName = jndiName;
}
}
}
You need to lookup your datasources from jndi instead of creating them using DataSourceBuilder. You can do it like this...
#Configuration
public class WeblogicResourceConfig {
private static final Logger log = LoggerFactory.getLogger(WeblogicResourceConfig.class);
#Autowired
private Environment env;
#Bean
public JndiTemplate jndiTemplate() {
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
return new JndiTemplate(props);
}
// destroyMethod MUST be blank or datasource is removed from jndi tree on
// see https://github.com/spring-projects/spring-framework/issues/17153
#Bean(destroyMethod = "")
#Primary
public DataSource primaryDataSource() throws NamingException {
return (DataSource) jndiTemplate().lookup(env.getProperty("spring.datasource.primary.jndi-name"));
}
// destroyMethod MUST be blank or datasource is removed from jndi tree
// see https://github.com/spring-projects/spring-framework/issues/17153
#Bean(destroyMethod = "")
public DataSource secondaryDataSource() throws NamingException {
return (DataSource) jndiTemplate().lookup(env.getProperty("spring.datasource.secondary.jndi"));
}
}
When creating your LocalContainerEntityManagerFactoryBean inject those datasources above instead of creating new DataSource beans.
I am trying to integrate 2 MySQL DBs in my Spring Boot JPA Application. I have followed the standard steps but still,
Steps Followed:
Added Multiple DB Credentials in Properties File
Created DB Configuration Classes to create Transaction & Entity Manager for Each DB
I am not able to resolve the below error:
[2020-03-24 18:07:48] - [Error starting Tomcat context. Exception: org.springframework.beans.factory.BeanCreationException. Message: Error creating bean with name 'com.oxfordcaps.finance.filter.AuthFilter': Cannot create inner bean '(inner bean)#7e52a26b' of type [com.oxfordcaps.finance.filter.AuthFilter] while setting bean property 'filter'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name '(inner bean)#7e52a26b': Unsatisfied dependency expressed through field 'userService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userServiceImpl': Unsatisfied dependency expressed through field 'userRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class com.oxfordcaps.finance.entity.User]
[2020-03-24 18:07:48] - [Stopping service [Tomcat]]
[2020-03-24 18:07:48] - [The web application [finance] appears to have started a thread named [HikariPool-1 housekeeper] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
java.lang.Thread.run(Thread.java:748)]
[2020-03-24 18:07:48] - [The web application [finance] appears to have started a thread named [HikariPool-1 connection adder] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.net.SocketInputStream.socketRead0(Native Method)
java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
java.net.SocketInputStream.read(SocketInputStream.java:171)
java.net.SocketInputStream.read(SocketInputStream.java:141)
com.mysql.cj.protocol.ReadAheadInputStream.fill(ReadAheadInputStream.java:107)
com.mysql.cj.protocol.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:150)
com.mysql.cj.protocol.ReadAheadInputStream.read(ReadAheadInputStream.java:180)
java.io.FilterInputStream.read(FilterInputStream.java:133)
com.mysql.cj.protocol.FullReadInputStream.readFully(FullReadInputStream.java:64)
com.mysql.cj.protocol.a.SimplePacketReader.readHeader(SimplePacketReader.java:63)
com.mysql.cj.protocol.a.SimplePacketReader.readHeader(SimplePacketReader.java:45)
com.mysql.cj.protocol.a.TimeTrackingPacketReader.readHeader(TimeTrackingPacketReader.java:52)
com.mysql.cj.protocol.a.TimeTrackingPacketReader.readHeader(TimeTrackingPacketReader.java:41)
com.mysql.cj.protocol.a.MultiPacketReader.readHeader(MultiPacketReader.java:54)
com.mysql.cj.protocol.a.MultiPacketReader.readHeader(MultiPacketReader.java:44)
com.mysql.cj.protocol.a.NativeProtocol.readMessage(NativeProtocol.java:535)
com.mysql.cj.protocol.a.NativeProtocol.checkErrorMessage(NativeProtocol.java:711)
com.mysql.cj.protocol.a.NativeProtocol.sendCommand(NativeProtocol.java:650)
com.mysql.cj.protocol.a.NativeProtocol.sendCommand(NativeProtocol.java:130)
com.mysql.cj.NativeSession.sendCommand(NativeSession.java:317)
com.mysql.cj.NativeSession.configureClientCharacterSet(NativeSession.java:550)
com.mysql.cj.jdbc.ConnectionImpl.initializePropsFromServer(ConnectionImpl.java:1307)
com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:958)
com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:817)
com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:447)
com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:237)
com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:199)
com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:136)
com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:369)
com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:198)
com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:467)
com.zaxxer.hikari.pool.HikariPool.access$100(HikariPool.java:71)
com.zaxxer.hikari.pool.HikariPool$PoolEntryCreator.call(HikariPool.java:706)
com.zaxxer.hikari.pool.HikariPool$PoolEntryCreator.call(HikariPool.java:692)
java.util.concurrent.FutureTask.run(FutureTask.java:266)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
java.lang.Thread.run(Thread.java:748)]
Caused by: java.lang.IllegalArgumentException: Not a managed type: class com.oxfordcaps.finance.entity.User
at org.hibernate.metamodel.internal.MetamodelImpl.managedType(MetamodelImpl.java:552)
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:74)
at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getEntityInformation(JpaEntityInformationSupport.java:66)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:201)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:151)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:134)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:65)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:305)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:297)
at org.springframework.data.util.Lazy.getNullable(Lazy.java:211)
at org.springframework.data.util.Lazy.get(Lazy.java:94)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:300)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:121)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774)
... 82 common frames omitted
Application File
#SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
#ServletComponentScan
#EnableScheduling
#EnableJpaRepositories({"com.oxfordcaps.finance.repository","com.oxfordcaps.student.repository"})
public class FinanceApplication {
public static void main(String[] args) {
SpringApplication.run(FinanceApplication.class, args);
}
#PostConstruct
public void init() {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
}
}
First Database Configuration file
DB Configuration 1
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* Database configuration
* #author prashant
*
*/
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactory",
basePackages = {"com.oxfordcaps.finance.repository"}
)
public class FinanceDataBaseConfiguration {
#Primary
#Bean(name = "datasource")
#ConfigurationProperties(prefix="spring.datasource")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
#Primary
#Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
return builder
.dataSource(primaryDataSource())
.packages("com.oxfordcaps.finance.entities")
.persistenceUnit("oxfordcaps")
.build();
}
#Primary
#Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager(
#Qualifier("entityManagerFactory") EntityManagerFactory
entityManagerFactory
) {
return new JpaTransactionManager(entityManagerFactory);
}
}
Second Database COnfiguration FIle
DB Configuration 2
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
/**
* Database configuration
* #author prashant
*
*/
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(
entityManagerFactoryRef = "studentEntityManagerFactory",
transactionManagerRef = "studentTransactionManager",
basePackages = {"com.oxfordcaps.student.repository"}
)
public class StudentDataBaseConfiguration {
#Bean(name = "studentDatasource")
#ConfigurationProperties(prefix="spring.second-datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
#Bean(name = "studentEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean studentEntityManagerFactory(EntityManagerFactoryBuilder builder) {
return
builder
.dataSource(dataSource())
.packages("com.oxfordcaps.student.model")
.persistenceUnit("oxfordcaps-student")
.build();
}
#Bean(name = "studentTransactionManager")
public PlatformTransactionManager studentTransactionManager(#Qualifier("studentEntityManagerFactory") EntityManagerFactory barEntityManagerFactory){
return new JpaTransactionManager(barEntityManagerFactory);
}
}
This is the Propety file which holds the db information in YML format
Properties File - YML
Database(MySQL) configuration
spring:
jpa:
hibernate:
ddl-auto: validate
show-sql: true
datasource:
jdbc-url: jdbc:mysql://stagingAAA.YYYYYYY.com:3306/YYYY_YYYY?useSSL=false
username: 0000
password: 0000
second-datasource:
jdbc-url: jdbc:mysql://stagingBBB.XXXXXXX.com:3306/XXXX_XXXX?useSSL=false
username: 0000
password: 0000
You are very likely missing the #Entity annotation on your User class (or it is in the wrong package, not being scanned).
At least, that's what your error message says:
Caused by: java.lang.IllegalArgumentException: Not a managed type: class com.oxfordcaps.finance.entity.User
In the stacktrace
Caused by: java.lang.IllegalArgumentException: Not a managed type: class com.oxfordcaps.finance.entity.User
at org.hibernate.metamodel.internal.MetamodelImpl.managedType(MetamodelImpl.java:552)
It might be because spring is not aware of the entity User
Try adding the annotation in FinanceApplication.java
#EntityScan("com.oxfordcaps.finance")
This might also help nested exception is java.lang.IllegalArgumentException: Not a managed type: class
Not a managed type: class com.oxfordcaps.finance.entity.User
First Database Configuration file DB Configuration 1
#Primary
#Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
return builder
.dataSource(primaryDataSource())
.packages("com.oxfordcaps.finance.entities") // !!! have to be: com.oxfordcaps.finance.entity
.persistenceUnit("oxfordcaps")
.build();
}
As a developer
I would like to develop a Spring JPA to access Oracle 9i database to fetch records via stored procedures
I want to connect to the database via application.yml but I initiate the project with the configuration file application.properties
I declare this in application.properties
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.hibernate.dialect=org.hibernate.dialect.Oracle9iDialect
spring.jpa.database=default
spring.main.allow-bean-definition-overriding=true
spring.datasource.driverClassName=oracle.jdbc.OracleDriver
spring.jpa.database-platform=org.hibernate.dialect.Oracle9iDialect
and in application.yml
jpa:
hibernate:
ddl-auto: none
naming:
physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
properties:
hibernate:
proc.param_null_passing: true
dialect: org.hibernate.dialect.Oracle9iDialect
show-sql: true
When it comes to execution, it raises the following exceptions
Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
Would you please tell me what other ways for me to modify the class or configuration file?
Here is my code of Configuration Class :
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy;
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;
#Configuration
#EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class})
#EnableTransactionManagement
#EnableJpaRepositories(
entityManagerFactoryRef = "productEntityManagerFactory",
transactionManagerRef = "productTransactionManager",
basePackages = {"com.pccw.ruby.repository"})
public class DBConfiguration {
#Primary
#Bean
#ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
#Primary
#Bean
LocalContainerEntityManagerFactoryBean entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(false);
vendorAdapter.setShowSql(true);
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(dataSource());
factoryBean.setJpaVendorAdapter(vendorAdapter);
factoryBean.setPackagesToScan("com.pccw.ruby.domain");
Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.proc.param_null_passing", new Boolean(true));
jpaProperties.put("hibernate.implicit_naming_strategy", SpringImplicitNamingStrategy.class.getName());
jpaProperties.put("hibernate.physical_naming_strategy", SpringPhysicalNamingStrategy.class.getName());
factoryBean.setJpaProperties(jpaProperties);
return factoryBean;
}
#Primary
#Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
Here is my oracle database version :
Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production
Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.proc.param_null_passing", new Boolean(true));
jpaProperties.put("hibernate.implicit_naming_strategy", SpringImplicitNamingStrategy.class.getName());
jpaProperties.put("hibernate.physical_naming_strategy", SpringPhysicalNamingStrategy.class.getName());
jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.Oracle9iDialect");
Try setting it here.
I have Spring based application and I need to get Hibernate working. So I got inspired by this tutorial: A Guide to Hibernate with Spring 4 and I created java class(I want to configure Hibernate xml-less):
package com.mycompany.cmms.web.config;
import java.util.Properties;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableTransactionManagement
public class PersistanceJPAConfig {
#Bean
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "com.vsb.cmms.domain" });
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em.getObject();
}
#Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.postgresql.Driver");
dataSource.setUrl("jdbc:postgresql://localhost:5432/cmms");
dataSource.setUsername( "postgres" );
dataSource.setPassword( "xxx" );
return dataSource;
}
#Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
return new PersistenceExceptionTranslationPostProcessor();
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
properties.setProperty("hibernate.query.factory_class", "org.hibernate.hql.internal.classic.ClassicQueryTranslatorFactory");
return properties;
}
}
But when I build and start my application i get this error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in com.vsb.cmms.web.config.PersistanceJPAConfig: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: 'entityManagerFactory' or 'persistenceUnitName' is required
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1583)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:751)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:444)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:326)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4717)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5179)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1404)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1394)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: 'entityManagerFactory' or 'persistenceUnitName' is required
at org.springframework.orm.jpa.JpaTransactionManager.afterPropertiesSet(JpaTransactionManager.java:304)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1642)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579)
... 21 more
The error is saying that'entityManagerFactory' or 'persistenceUnitName' is required. But entity manager factory should be provided via entityManagerFactory().
When I debbuged thi bean I noticed that em.getObject() is returning null and possibly is causing the error although I do not know why is this happening. I am using Spring 4 and Hibernate 5.2.3.Final.
Your entityManagerFactory() method really shouldn't be calling #getObject() but instead you should write it as:
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "com.vsb.cmms.domain" });
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
// just return the bean here
return em;
}
Spring handles that factory bean automatically giving your EntityManagerFactory instances.
Just found in the deeps of the internet...
If you want to make xml-less hibernate configuration with a chance easily control session(session for application or session for transaction), then you probably want to see this
Please note, the code as it is works perfectly until Hibernate 5.2 version
I have some problem when inherit session factory and configuration from another project :
I have two separate project (core-project, the projects uses core as library)
configuration of my core-project is the following code :
package ir.badnava.pressmining.core.config;
import java.util.Properties;
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.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import ir.badnava.pressmining.core.models.raw.base.BaseRawEntity;
import ir.badnava.pressmining.core.models.raw.page.RawPageEntity;
#Configuration
#ComponentScan(basePackages = { "ir.badnava.pressmining" })
#EnableTransactionManagement
#PropertySource(value = { "classpath:database.properties" })
public class AppConfig {
#Autowired
private Environment environment;
#Bean(name = "sessionFactory")
public LocalSessionFactoryBean getSessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(getDataSource());
setAnotatedClasses(sessionFactory);
sessionFactory.setHibernateProperties(getHibernateProperties());
return sessionFactory;
}
protected void setAnotatedClasses(LocalSessionFactoryBean sessionFactory) {
sessionFactory.setAnnotatedClasses(new Class<?>[]{BaseRawEntity.class, RawPageEntity.class});
}
#Bean(name = "dataSource")
public DataSource getDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
return dataSource;
}
private Properties getHibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto"));
return properties;
}
#Autowired
#Bean(name = "transactionManager")
public HibernateTransactionManager getTransactionManager(SessionFactory s) {
HibernateTransactionManager txManager = new HibernateTransactionManager(s);
return txManager;
}
}
and the child project configuration is the following code :
package com.badnava.pressmining.web.crawler.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import com.badnava.pressmining.web.crawler.crawler.WebCrawler;
import com.badnava.pressmining.web.crawler.models.speciallist.RepositoryList;
import com.badnava.pressmining.web.crawler.models.speciallist.RepositoryListManager;
import com.badnava.pressmining.web.crawler.models.urlrepo.UrlRepository;
import com.badnava.pressmining.web.crawler.models.urlrepo.UrlRepositoryManager;
#Configuration
public class AppConfig extends ir.badnava.pressmining.core.config.AppConfig{
#Bean
public RepositoryListManager getRepositoryListManager() {
return new RepositoryListManager();
}
#Bean
public UrlRepositoryManager getUrlRepositoryManager() {
return new UrlRepositoryManager();
}
#Bean
public WebCrawler getWebCrawler(){
return new WebCrawler();
}
#Override
protected void setAnotatedClasses(LocalSessionFactoryBean sessionFactory) {
super.setAnotatedClasses(sessionFactory);
sessionFactory.setAnnotatedClasses(new Class<?>[]{RepositoryList.class, UrlRepository.class});
}
}
and my problem is that in the child project I overload the setAnnotatedClass method and calling it's super and give the session factory my entities class but after doing something like save or update session factory says that unknown mapping entity
I have no idea about what did I wrong in these code because I did that before with XML file configuration
Update :
log :
Exception in thread "Thread-3" org.hibernate.MappingException: Unknown entity: ir.badnava.pressmining.core.models.raw.page.RawPageEntity
at org.hibernate.internal.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:776)
at org.hibernate.internal.SessionImpl.getEntityPersister(SessionImpl.java:1533)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:104)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:682)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:674)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:669)
at ir.badnava.pressmining.core.models.raw.base.BaseDao.save(BaseDao.java:16)
at ir.badnava.pressmining.core.models.raw.base.BaseDao$$FastClassBySpringCGLIB$$d95ff2ca.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:280)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
at ir.badnava.pressmining.core.models.raw.base.BaseDao$$EnhancerBySpringCGLIB$$95dae3fd.save(<generated>)
at ir.badnava.pressmining.core.models.raw.base.BaseManager.save(BaseManager.java:23)
at com.badnava.pressmining.web.crawler.crawler.WebCrawler$3.run(WebCrawler.java:142)
at java.lang.Thread.run(Thread.java:745)
Problem solved :
the problem was that the setAnnotatedClasses method is a setter method and I changed my code to bellow code and that's work
#Override
protected Class<?>[] setAnotatedClasses() {
Class<?>[] superClasses = super.setAnotatedClasses(sessionFactory);
Class<?>[] childClasses = new Class<?>[]{RepositoryList.class, UrlRepository.class};
Class<?>[] allClasses = new Class<?>[childClasses.length + superClasses.length];
for (int i = 0; i < allClasses.length; i++) {
if (i < superClasses.length)
allClasses[i] = superClasses[i];
else
allClasses[i] = childClasses[i-childClasses.length];
}
return allClasses;
}
thanks to #sura2k