EntityManager doesn't translate camel case to snake case - java

I'm using SpringBoot 2.7.0 and trying to set an entity manager cause I have 2 databases.
But the entityManager that I instantiated doesn't work like default one.
It doesn't translate camel case to snake case for the properties of entity when it creates tables.
Even it doesn't follow the settings in application.yml. for example, spring.jpa.show-sql.
I configured it with below code.
#Slf4j
#RequiredArgsConstructor
#EnableJpaAuditing
#EnableJpaRepositories(basePackages = "com.xxx.yyy", entityManagerFactoryRef = "businessEntityManagerFactory", transactionManagerRef = "businessTransactionManager")
#EntityScan(basePackages = "com.xxx.yyy")
#Configuration
public class JpaConfiguration {
#Bean
public LocalContainerEntityManagerFactoryBean businessEntityManagerFactory(EntityManagerFactoryBuilder builder,
DataSource businessDataSource) {
return builder
.dataSource(businessDataSource)
.packages("com.xxx.yyy")
.build();
}
#Bean
public PlatformTransactionManager businessTransactionManager(LocalContainerEntityManagerFactoryBean businessEntityManagerFactory) {
return new JpaTransactionManager(Objects.requireNonNull(businessEntityManagerFactory.getObject()));
}
}
Does anyone know how I can instantiate an entity manager with same settings like spring boot default one?

Spring's convention-over-configuration does not work well with multiple database configurations.
Particuallary the configuration has to be autowired "manually". That's the reason springt.jpa.show-sql is not considered.
I will post an example on how to configure a database "manually".
import java.util.Map;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration;
import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration;
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.jdbc.JdbcTemplateAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
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.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.persistenceunit.PersistenceUnitManager;
import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.zaxxer.hikari.HikariDataSource;
#Configuration
#EnableTransactionManagement
#EnableAutoConfiguration(exclude = {JdbcRepositoriesAutoConfiguration.class, JpaRepositoriesAutoConfiguration.class, DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class, JdbcTemplateAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
#EnableJpaRepositories(basePackageClasses = {ExampleXyzRepository.class}, transactionManagerRef = DatabaseConfig.SPRING_TRANSACTION_MANAGER)
public class DatabaseConfig {
public static final String SPRING_TRANSACTION_MANAGER = "springTransactionManager";
private static LocalContainerEntityManagerFactoryBean createEntityManagerFactory(
final ObjectProvider<PersistenceUnitManager> persistenceUnitManagerProvider, final JpaProperties jpaProperties,
final HibernateProperties hibernateProperties, final DataSource dataSource, final Class<?> exampleEntityClass, final String persistenceUnit) {
return createEntityManagerFactoryBuilder(persistenceUnitManagerProvider.getIfAvailable(), jpaProperties, hibernateProperties)
.dataSource(dataSource)
.packages(exampleEntityClass)
.persistenceUnit(persistenceUnit)
.build();
}
private static EntityManagerFactoryBuilder createEntityManagerFactoryBuilder(
final PersistenceUnitManager persistenceUnitManager, final JpaProperties jpaProperties, final HibernateProperties hibernateProperties) {
final JpaVendorAdapter jpaVendorAdapter = createJpaVendorAdapter(jpaProperties);
final Map<String, Object> expandedProperties = hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
return new EntityManagerFactoryBuilder(jpaVendorAdapter, expandedProperties, persistenceUnitManager);
}
private static JpaVendorAdapter createJpaVendorAdapter(final JpaProperties jpaProperties) {
final AbstractJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setShowSql(jpaProperties.isShowSql());
adapter.setDatabasePlatform(jpaProperties.getDatabasePlatform());
adapter.setGenerateDdl(jpaProperties.isGenerateDdl());
if (jpaProperties.getDatabase() != null) {
adapter.setDatabase(jpaProperties.getDatabase());
}
return adapter;
}
private static HikariDataSource initializeDataSource(final DataSourceProperties dataSourceProperties) {
return dataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
}
#Bean
#ConfigurationProperties("spring.datasource")
public DataSourceProperties springDataSourceProperties() {
return new DataSourceProperties();
}
#Bean
#ConfigurationProperties("spring.datasource.hikari")
public DataSource springDataSource(#Qualifier("springDataSourceProperties") final DataSourceProperties springDataSourceProperties) {
return initializeDataSource(springDataSourceProperties);
}
#Bean
#ConfigurationProperties("spring.jpa")
public JpaProperties springJpaProperties() {
return new JpaProperties();
}
#Bean
#ConfigurationProperties("spring.jpa.hibernate")
public HibernateProperties springHibernateProperties() {
return new HibernateProperties();
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
final ObjectProvider<PersistenceUnitManager> persistenceUnitManagerProvider,
#Qualifier("springJpaProperties") final JpaProperties springJpaProperties,
#Qualifier("springHibernateProperties") final HibernateProperties springHibernateProperties,
#Qualifier("springDataSource") final DataSource springDataSource) {
return createEntityManagerFactory(persistenceUnitManagerProvider, springJpaProperties, springHibernateProperties, springDataSource, ExampleXyzEntity.class, "default-persistence-unit");
}
#Bean(SPRING_TRANSACTION_MANAGER)
public JpaTransactionManager transactionManager(#Qualifier("entityManagerFactory") final EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
See how the configuration of DataSourceProperties, HibernateProperties, DataSource and JpaProperties are bound.
The second database is configured similar.
But:
use a different configuration prefix and not spring.jpa and spring.datasource - obviously
define the transactionManager in the org.springframework.transaction.annotation.Transactional while accessing the second database, e.g. in the CrudRepository

Sven's answer might be right but I didn't try it because I saw this after I found the solution and it looked requiring many changes my codes.
I figured this out with below codes
#Bean
public LocalContainerEntityManagerFactoryBean businessEntityManagerFactory(DataSource businessDataSource) {
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(businessDataSource);
emf.setPackagesToScan("com.xxx.yyy");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setShowSql(Boolean.valueOf(env.getProperty("spring.jpa.show-sql")));
emf.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.dialect", env.getProperty("spring.jpa.properties.hibernate.dialect"));
properties.put("hibernate.format_sql", env.getProperty("spring.jpa.properties.hibernate.format_sql"));
properties.put("hibernate.hbm2ddl.auto", env.getProperty("spring.jpa.properties.hibernate.hbm2ddl.auto"));
properties.put("hibernate.physical_naming_strategy", "org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy");
properties.put("hibernate.implicit_naming_strategy", "org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy");
emf.setJpaPropertyMap(properties);
return emf;
}

Related

Bean overriding although there is no overrided bean

I am implementing a read-only db source but although there is no conflicting bean, it got bean error.
How can I fix the below issue ?
The bean 'routingDataSource', defined in class path resource [io/api/masterSlave/datasources/DataSourcesConfiguration.class], could not be registered. A bean with that name has already been defined in file [/Users/neslihan.bozer/Codes/api-backend/target/classes/io/api/masterSlave/routing/RoutingDataSource.class] and overriding is disabled.
package io.api.masterSlave.datasources;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import io.api.masterSlave.properties.Properties;
import io.api.masterSlave.routing.RoutingDataSource;
#Configuration
#ComponentScan
#EnableJpaRepositories("io.api.persistence.repository")
public class DataSourcesConfiguration {
#Autowired
private Properties props;
#Bean(name = "masterDataSource1")
#Primary
public DataSource masterDataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(props.getProperty("spring.datasource.master.driver-class-name"));
dataSource.setDefaultAutoCommit(false);
dataSource.setUsername(props.getProperty("spring.datasource.master.username"));
dataSource.setPassword(props.getProperty("spring.datasource.master.password"));
dataSource.setUrl(props.getProperty("spring.datasource.master.url"));
return dataSource;
}
#Bean
public RoutingDataSource routingDataSource() {
RoutingDataSource dataSource = new RoutingDataSource();
dataSource.setDefaultTargetDataSource(masterDataSource());
Map<Object, Object> targets = new HashMap<>();
targets.put(DataSourceType.MASTER, masterDataSource());
targets.put(DataSourceType.SLAVE, slaveDataSource());
dataSource.setTargetDataSources(targets);
dataSource.afterPropertiesSet();
return dataSource;
}
#Bean(name = "slaveDataSource2")
public DataSource slaveDataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(props.getProperty("spring.datasource.slave.driver-class-name"));
dataSource.setDefaultAutoCommit(false);
dataSource.setUsername(props.getProperty("spring.datasource.slave.username"));
dataSource.setPassword(props.getProperty("spring.datasource.slave.password"));
dataSource.setUrl(props.getProperty("spring.datasource.slave.url"));
return dataSource;
}
#Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(masterDataSource());
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(Boolean.parseBoolean(props.getProperty("spring.jpa.generate-ddl")));
Map<String, String> additionalProperties = new HashMap<>();
additionalProperties.put("hibernate.dialect", props.getProperty("spring.jpa.dialect"));
LocalContainerEntityManagerFactoryBean factory = builder.dataSource(routingDataSource())
.packages("io.api.persistence.entity").persistenceUnit("routingEntityMF").properties(additionalProperties)
.build();
factory.setJpaVendorAdapter(vendorAdapter);
factory.afterPropertiesSet();
return factory;
}
}
RoutingDataSource.java
package io.api.masterSlave.routing;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.stereotype.Service;
#Service
public class RoutingDataSource extends AbstractRoutingDataSource {
#Autowired
private DbHolder dbHolder;
#Override
protected Object determineCurrentLookupKey() {
return dbHolder.getDbType();
}
}

Relationship between two entities of different schemes - Spring Boot Data JPA

Is it possible to cross join between two different database tables (2 DataSources) in Spring Boot using JPA? If so, how would you configure this configuration? In the application.properties, 4 databases are already being defined and 4 files have been created that represent the configurations of the DataSources. The scenario is that there is a DataSource 1 table that has a FOREIGN KEY with a DataSource 2 table, but when the application is raised an Exception is generated:
#OneToOne or #ManyToOne on com.smart4.bdcentral.domain.files.IndividuoFoto .persons references an unknown entity: com.smart4.bdcentral.domain.main.IndividuoPessoa
DataSource 1
package com.smart4.configBases;
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.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import com.google.common.base.Preconditions;
#Configuration
#PropertySource({ "classpath:application.properties" })
#EnableJpaRepositories(basePackages = {"com.smart4.bdcentral.repository.main"},
entityManagerFactoryRef = "bdCentralMainEntityManager",
transactionManagerRef = "bdCentralMainTransactionManager")
public class BdCentralMain {
#Autowired
private Environment env;
public BdCentralMain() {
super();
}
#Bean
public LocalContainerEntityManagerFactoryBean bdCentralMainEntityManager() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(bdCentralMainDataSource());
em.setPackagesToScan(new String[] { "com.smart4.bdcentral.domain.main" });
em.setPersistenceUnitName("bdcentralmain");
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabase(Database.MYSQL);
vendorAdapter.setShowSql(false);
vendorAdapter.setGenerateDdl(true);
vendorAdapter.setDatabasePlatform("org.hibernate.dialect.MySQL5Dialect");
em.setJpaVendorAdapter(vendorAdapter);
final HashMap<String, Object> properties = new HashMap<String, Object>();
properties.put("hibernate.hbm2ddl.auto", env.getProperty("bdcentralmain.hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect", env.getProperty("bdcentralmain.hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
#Bean
public DataSource bdCentralMainDataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource
.setDriverClassName(Preconditions.checkNotNull(env.getProperty("bdcentralmain.jdbc.driverClassName")));
dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("bdcentralmain.jdbc.url")));
dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("bdcentralmain.jdbc.user")));
dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("bdcentralmain.jdbc.pass")));
return dataSource;
}
#Bean
public PlatformTransactionManager bdCentralMainTransactionManager() {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(bdCentralMainEntityManager().getObject());
return transactionManager;
}
}
DataSource 2
package com.smart4.configBases;
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.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import com.google.common.base.Preconditions;
#Configuration
#PropertySource({ "classpath:application.properties" })
#EnableJpaRepositories(basePackages = {"com.smart4.bdcentral.repository.files"},
entityManagerFactoryRef = "bdCentralFilesEntityManager",
transactionManagerRef = "bdCentralFilesTransactionManager")
public class BdCentralFiles {
#Autowired
private Environment env;
public BdCentralFiles() {
super();
}
#Bean
public LocalContainerEntityManagerFactoryBean bdCentralFilesEntityManager() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(bdCentralFilesDataSource());
em.setPackagesToScan(new String[] { "com.smart4.bdcentral.domain.files" });
em.setPersistenceUnitName("bdcentralfiles");
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabase(Database.MYSQL);
vendorAdapter.setShowSql(false);
vendorAdapter.setGenerateDdl(true);
vendorAdapter.setDatabasePlatform("org.hibernate.dialect.MySQL5Dialect");
em.setJpaVendorAdapter(vendorAdapter);
final HashMap<String, Object> properties = new HashMap<String, Object>();
properties.put("hibernate.hbm2ddl.auto", env.getProperty("bdcentralfiles.hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect", env.getProperty("bdcentralfiles.hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
#Bean
public DataSource bdCentralFilesDataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource
.setDriverClassName(Preconditions.checkNotNull(env.getProperty("bdcentralfiles.jdbc.driverClassName")));
dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("bdcentralfiles.jdbc.url")));
dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("bdcentralfiles.jdbc.user")));
dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("bdcentralfiles.jdbc.pass")));
return dataSource;
}
#Bean
public PlatformTransactionManager bdCentralFilesTransactionManager() {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(bdCentralFilesEntityManager().getObject());
return transactionManager;
}
}
not much to say with just the datasources, check the annotation configuration and make sure your objects are #Entity annotated. It doesn't sound like you actually want a "cross join", also you're looking at Hibernate, I kept reading Spring Boot JPA as spring "Data" JPA and was getting confused as to why it wasn't data jpa lol.

How to fix Error creating bean with name 'sessionFactory' error?

Trying to make some webapp with java? spring and hibernate. I am noob in java.
Nake all by the manual, but getting error
Error creating bean with name 'sessionFactory' defined in dev.test.config.HibernateConfig: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError
My HibernateConfig.Java
package dev.test.config;
import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
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.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.Properties;
#Configuration
#ComponentScan(basePackages = "dev.test")
#EnableTransactionManagement
#PropertySource(value = "classpath:/db.properties")
public class HibernateConfig {
private Environment environment;
#Autowired
public void setEnvironment(Environment environment) {
this.environment = environment;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
return properties;
}
#Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
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;
}
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan("dev.test.models");
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
}
In DAO file just add
#Autowired
private SessionFactory sessionFactory;
Before this changes? when i try to make app with temporary storage(just dict in app) all work.
Would be very glad for any help.

Table is not being created, despite `hibernate.hbm2ddl.auto=update` in application.properties

For some reason, my db tables are not being created according to the entity model in the codebase. I am looking for the codebase to lead, and create the tables in the db, every time the server starts.
I have this in src/main/resources/application.properties
################### DataSource Configuration ##########################
jdbc.driverClassName=org.h2.Driver
jdbc.url=jdbc:h2:~/test
jdbc.username=sa
jdbc.password=
################### spring config ####################################
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=create
################### Hibernate Configuration ##########################
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=update
I bet some of that is redundant or maybe even contradictory. I doubt I need spring.jpa and hibernate, since they conflict. My current preference is to use Hibernate for ORM.
I also have:
package huru.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* Trivial JPA entity for vertx-spring demo
*/
#Entity
#Table(name="HURU_USER")
public class User {
#Id
#Column(name="ID")
private Integer productId;
#Column
private String description;
public Integer getProductId() {
return this.productId;
}
public String getDescription() {
return this.description;
}
}
and I have this:
package huru.repository;
import huru.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* Spring Data JPA repository to connect our service bean to data
*/
public interface UserRepository extends JpaRepository<User, Integer> {
}
and here is the SpringConfiguration
package huru.config;
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.core.io.ClassPathResource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.datasource.init.DatabasePopulator;
import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
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.Properties;
/**
* Simple Java Spring configuration to be used for the Spring example application. This configuration is mainly
* composed of a database configuration and initial population via the script "products.sql" of the database for
* querying by our Spring service bean.
* <p>
* The Spring service bean and repository are scanned for via #EnableJpaRepositories and #ComponentScan annotations
*/
#Configuration
#EnableJpaRepositories(basePackages = {"huru.repository"})
#PropertySource(value = {"classpath:application.properties"})
#ComponentScan("huru.service")
public class SpringConfiguration {
#Autowired
private Environment env;
#Bean
#Autowired
public DataSource dataSource(DatabasePopulator populator) {
final DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName(env.getProperty("jdbc.driverClassName"));
ds.setUrl(env.getProperty("jdbc.url"));
ds.setUsername(env.getProperty("jdbc.username"));
ds.setPassword(env.getProperty("jdbc.password"));
DatabasePopulatorUtils.execute(populator, ds);
return ds;
}
#Bean
#Autowired
public LocalContainerEntityManagerFactoryBean entityManagerFactory(final DataSource dataSource) {
final LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setDataSource(dataSource);
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(Boolean.TRUE);
vendorAdapter.setShowSql(Boolean.TRUE);
factory.setDataSource(dataSource);
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("huru.entity");
Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
jpaProperties.put("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
factory.setJpaProperties(jpaProperties);
return factory;
}
#Bean
#Autowired
public PlatformTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory.getObject());
}
#Bean
public DatabasePopulator databasePopulator() {
final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.setContinueOnError(false);
populator.addScript(new ClassPathResource("users.sql"));
return populator;
}
}
package huru.config;
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.core.io.ClassPathResource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.datasource.init.DatabasePopulator;
import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
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.Properties;
/**
* Simple Java Spring configuration to be used for the Spring example application. This configuration is mainly
* composed of a database configuration and initial population via the script "products.sql" of the database for
* querying by our Spring service bean.
* <p>
* The Spring service bean and repository are scanned for via #EnableJpaRepositories and #ComponentScan annotations
*/
#Configuration
#EnableJpaRepositories(basePackages = {"huru.repository"})
#PropertySource(value = {"classpath:application.properties"})
#ComponentScan("huru.service")
public class SpringConfiguration {
#Autowired
private Environment env;
#Bean
#Autowired
public DataSource dataSource(DatabasePopulator populator) {
final DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName(env.getProperty("jdbc.driverClassName"));
ds.setUrl(env.getProperty("jdbc.url"));
ds.setUsername(env.getProperty("jdbc.username"));
ds.setPassword(env.getProperty("jdbc.password"));
DatabasePopulatorUtils.execute(populator, ds);
return ds;
}
#Bean
#Autowired
public LocalContainerEntityManagerFactoryBean entityManagerFactory(final DataSource dataSource) {
final LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setDataSource(dataSource);
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(Boolean.TRUE);
vendorAdapter.setShowSql(Boolean.TRUE);
factory.setDataSource(dataSource);
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("huru.entity");
Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
jpaProperties.put("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
factory.setJpaProperties(jpaProperties);
return factory;
}
#Bean
#Autowired
public PlatformTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory.getObject());
}
#Bean
public DatabasePopulator databasePopulator() {
final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.setContinueOnError(false);
populator.addScript(new ClassPathResource("users.sql"));
return populator;
}
}
so yeah like I said, I am hoping to see a table called "USER" in the db, but it doesn't seem to be happening.
Yeah the datasource info in application.properties was wrong, should have looked like this instead:
jdbc.driverClassName=org.postgresql.Driver
jdbc.url=jdbc:postgresql://localhost:5432/oleg
jdbc.username=postgres
jdbc.password=postgres

hibernate 5 - Could not obtain transaction-synchronized Session for current thread;

I am able to use sessions if I open a new one, however, I am getting this error if I try to get the current session which I guess doesn't exist.
persistence-h2.properties
# jdbc.X
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/my-database
jdbc.eventGeneratedId=sa
jdbc.user=root
jdbc.pass=root_password
# hibernate.X
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=false
hibernate.hbm2ddl.auto=validate
# hibernate.search.X
hibernate.search.default.directory_provider = filesystem
hibernate.search.default.indexBase = /data/index/default
# envers.X
envers.audit_table_suffix=_audit_log
HibernateConfig.java
package com.buraktas.spring;
import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
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.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.Properties;
#Configuration
#EnableTransactionManagement
#PropertySource({ "classpath:persistence-h2.properties" })
#ComponentScan({ "com.buraktas" })
public class HibernateConfig {
#Autowired
private Environment env;
#Bean
public LocalSessionFactoryBean sessionFactory() {
final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[] { "com.buraktas.model" });
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean
public DataSource dataSource() {
final BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
dataSource.setUrl(env.getProperty("jdbc.url"));
dataSource.setUsername(env.getProperty("jdbc.user"));
dataSource.setPassword(env.getProperty("jdbc.pass"));
return dataSource;
}
#Bean
public PlatformTransactionManager hibernateTransactionManager() {
final HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
private final Properties hibernateProperties() {
final Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
hibernateProperties.setProperty("hibernate.show_sql", "true");
// Envers properties
hibernateProperties.setProperty("org.hibernate.envers.audit_table_suffix", env.getProperty("envers.audit_table_suffix"));
return hibernateProperties;
}
}
PersonDaoImp.java
#Repository
public class PersonDaoImp implements PersonDao {
#Autowired
private SessionFactory sessionFactory;
public Person getPerson(int id) {
Session currentSession = sessionFactory.getCurrentSession();
return currentSession.get(Person.class, 1);
}
}
Here if I use sessionFactory.openSession() instead then I am able to query my database. But I don't want to create a new session and close it every time. I thought I needed to add current_session_context_class and connection.pool_size properties as well, but that didn't solve the problem. So long story short how I can initialize a connection pool or a session pool?
Thanks!
This is a late response, but as I mentioned in the comments adding #Transactional on class level worked.

Categories

Resources