spring jpa batch update doesn't work - not spring boot - spring

I have a project, which is not a spring boot project, but it uses different spring framework libraries (spring-data-jpa, spring-security-web, sping-mvc, etc), and hibernate-core, hibernate-entitymanager.
The database is postgresql.
I have difficulties setup database batch processing for updates. Practically running JpaRepository.saveAll method with a List
tried to setup properties in application.properties file:
spring.jpa.properties.hibernate.generate_statistics=true
spring.jpa.properties.hibernate.jdbc.batch_size=10
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true
doesn't work
tried to setup properties in the ApplicationContext class as entityManagerFactoryBean
#Bean(name = "entityManagerFactory")
#DependsOn("flyway")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
...
Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.generate_statistics", "true");
jpaProperties.put("hibernate.jdbc.batch_size", "25");
jpaProperties.put("hibernate.order_inserts", "true");
jpaProperties.put("hibernate.order_updates", "true");
entityManagerFactoryBean.setJpaProperties(jpaProperties);
return entityManagerFactoryBean;
}
also doesn't work.
but even the statistics are not reporting, though i have setup logging.level.org.hibernate=INFO
what is the solution if there is no spring-boot?

Related

Spring boot with apache OpenJPA

I am trying to integrate my test spring boot application with DB.
I don't want to use Hibernate vendor, I want to use apache OpenJPA.
My current bootstrap.yml looks like this
spring:
datasource:
url: jdbc:oracle:thin:#xxxx:1521:xxx
username: xxxx
password: xxxx
driver-class-name: oracle.jdbc.OracleDriver
Is it possible to set dialect to work with OpenJPA?
Does spring supports today OpenJpa?
If you could provide some example of configuration it would be great.
Thank in advance.
upd: In example founded here - configure openjpa on to spring boot I see that used OpenJpaVendorAdapter which does not exist in spring 5.
In documentation of spring-data https://docs.spring.io/spring-data/jpa/docs/current/reference/html/ said that
Spring Data JPA 1.10 added the following features:
Upgrade to Querydsl 4, Hibernate 5, OpenJPA 2.4, and EclipseLink 2.6.1.
However I still don't see the proper way to configure it.
According to this page, You can not use Open Jpa with spring 5.
But this is an example for spring 4.
#Configuration
#EnableTransactionManagement
#PropertySource("classpath:application.properties")
#EnableJpaRepositories(basePackages = "com.baoviet.mhol.persistence.dao")
#ComponentScan("com.baoviet.mhol.service")
public class JpaConfig {
#Bean(destroyMethod ="" )
public DataSource dataSource(#Value("${db.jndi}") String jndiName) {
JndiDataSourceLookup lookup = new JndiDataSourceLookup();
lookup.setResourceRef(true);
return lookup.getDataSource(jndiName);
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
lef.setDataSource(dataSource);
lef.setJpaVendorAdapter(jpaVendorAdapter);
lef.setPackagesToScan("com.baoviet.mhol.persistence.model");
lef.setJpaDialect(new OpenJpaDialect());
return lef;
}
#Bean
public JpaVendorAdapter jpaVendorAdapter() {
OpenJpaVendorAdapter OpenJpaVendorAdaptor = new OpenJpaVendorAdapter();
OpenJpaVendorAdaptor.setShowSql(true);
OpenJpaVendorAdaptor.setGenerateDdl(true);
OpenJpaVendorAdaptor.setDatabasePlatform("org.OpenJpa.dialect.Oracle10gDialect");
return OpenJpaVendorAdaptor;
}
#Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
}
}
Remember, in this case You do not need to persistence.xml file.
And This is Application.properties.
db.jndi=jdbc/batch
Note:
OpenJpa needs Persistence.xml to enhance entities at compile time.
So, You need to use different method for entity enhancement or provide your metadata in xml other than persistence.xml or use persistence.xml instead of data source.
You need to search for these more.
for entity enhancement solutions, please visit hear

Hibernate MultiTenancy with spring jpa

I want to add multiple tenant into my application using separate schema.My application is based on spring jpa and hibernate. I implement MultiTenantConnectionProvider and CurrentTenantIdentifierResolver.
And my configuration class is:
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource){
LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
entityManagerFactory.setPackagesToScan("com.**.api.entity");
HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
entityManagerFactory.setJpaVendorAdapter(hibernateJpaVendorAdapter);
Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.globally_quoted_identifiers",true);
jpaProperties.put("hibernate.dialect",org.hibernate.dialect.MySQL5Dialect.class);
jpaProperties.put("hibernate.multi_tenant_connection_provider",multiTenantConnectionProvider);
jpaProperties.put("hibernate.tenant_identifier_resolver",currentTenantIdentifierResolver);
jpaProperties.put("hibernate.multiTenancy","SCHEMA");
entityManagerFactory.setJpaProperties(jpaProperties);
return entityManagerFactory;
}
And I use MapDataSourceLookup to save dataSources.It works.But it's a little problem. I must assign the packagesToScan.I want it to be a basic service.And some application depend on it.It seems that assign the packagesToScan is not a good practice.
Is there any better way to do it?

Spring Data JPA and Connection Pooling

I have a RESTful web application which stores data against Oracle and the stack is Spring-Data-Jpa and Hibernate.
We have implemented connection pooling using Oracle UCP, but it does not seem to work. There were 1000s of connections in the DB for our NFT tests.
My config is as shown below
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws IllegalStateException, SQLException {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
entityManagerFactoryBean.setPackagesToScan(env.getRequiredProperty(ENTITYMANAGER_PACKAGES_TO_SCAN));
entityManagerFactoryBean.setJpaProperties(hibProperties());
return entityManagerFactoryBean;
}
#Bean
public DataSource dataSource() throws IllegalStateException, SQLException {
PoolDataSource dataSource = PoolDataSourceFactory.getPoolDataSource();
dataSource.setConnectionFactoryClassName(env.getRequiredProperty(DB_CONNECTION_FACTORY_CLASS_NAME));
dataSource.setURL(env.getRequiredProperty(DATABASE_URL));
dataSource.setUser(env.getRequiredProperty(DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty(DATABASE_PASSWORD));
dataSource.setMinPoolSize(Integer.parseInt(env.getRequiredProperty(DATABASE_CONNECTION_MIN_POOL_SIZE)));
dataSource.setMaxPoolSize(Integer.parseInt(env.getRequiredProperty(DATABASE_CONNECTION_MAX_POOL_SIZE)));
dataSource.setInitialPoolSize(Integer.parseInt(env.getRequiredProperty(DATABASE_CONNECTION_INITIAL_POOL_SIZE)));
return dataSource;
}
private Properties hibProperties() {
Properties properties = new Properties();
properties.put(HIBERNATE_DIALECT, env.getRequiredProperty(HIBERNATE_DIALECT));
properties.put(HIBERNATE_SHOW_SQL, env.getRequiredProperty(HIBERNATE_SHOW_SQL));
/*properties.put(HIBERNATE_NAMING_STRATEGY, env.getRequiredProperty(HIBERNATE_NAMING_STRATEGY));*/
return properties;
}
Let me know if there is another config I should be using here, such that a new session is not created all the time.
Thanks
Kris
It would seem that a DataSource gets created for each thread and centralising the datasource in the Jetty config sorted the problem.
jetty and Oracle Connection Pooling

Integrating Hibernate OGM and Spring Data JPA

How can we integrate Hibernate OGM with Spring Data JPA, so that existing application containing Hibernate ORM can be used with Hibernate OGM.
This is the configuration i'm currently using for Hibernate ORM
#Bean(name = "jdbc")
public DriverManagerDataSource getDriverManager() {
DriverManagerDataSource driverManagerDataSource = new
DriverManagerDataSource(
env.getProperty(dataBase + ".url"), env.getProperty(dataBase +
".username"),
env.getProperty(dataBase + ".password"));
driverManagerDataSource.setDriverClassName(env.getProperty(dataBase +
".driver"));
return driverManagerDataSource;
}
#Bean(name = "japaImplementation")
public HibernateJpaVendorAdapter getHibernate() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabasePlatform(env.getProperty(dataBase + ".dialect"));
vendorAdapter.setGenerateDdl(true);
vendorAdapter.setShowSql(true);
return vendorAdapter;
}
#Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean
getEntityManagerFactoryBean() {
LocalContainerEntityManagerFactoryBean factoryBean = new
LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(getDriverManager());
factoryBean.setJpaVendorAdapter(getHibernate());
factoryBean.setPackagesToScan("com.xyz.abc.entity");
return factoryBean;
}
I just had a quick glance at Hibernate OGM. It seems it is just a JPA implementation. So Spring Data JPA should work out of the box for it. Although up to now it does not get tested against it.
But it raises the question, why you would want to do that? There are already Spring Data modules for most, if not all of the data stores supported by Hibernate OGM. So why don't you use Spring Data MongoDB directly?
The projects are more alternatives to each other than something to let one run on top of the other. See this question for arguments from both sides.

problems configuring Hibernate with spring boot, CommandLineRunner

I'm using Spring Tool Suite to create a Spring Boot application that uses Hibernate.
Here's my application.properties file:
spring.datasource.url=jdbc:mysql:someurl
spring.datasource.username=somename
spring.datasource.password=somepassword
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=create
spring.jpa.database-platform=org.hibernate.dialect.SQLServerDialect
spring.jpa.show-sql=true
I'm trying to run the following CommandLineRunner:
#Bean
public CommandLineRunner demo(CustomerRepository repository) {
return (args) -> {
Configuration configuration = new Configuration().configure();
ServiceRegistryBuilder registry = new ServiceRegistryBuilder();
registry.applySettings(configuration.getProperties());
ServiceRegistry serviceRegistry = registry.buildServiceRegistry();
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
Session session = sessionFactory.openSession();
Transaction t = session.beginTransaction();
Customer e1 = new Customer();
//blah blah blah
session.persist(e1);
t.commit();
session.close();
};
}
My problem is:
Configuration configuration = new Configuration().configure();
looks for "hibernate.cfg.xml" and all my hibernate config is in application.properties
How do I cause the Hibernate config stuff to initialize itself with the stuff in application.properties?
Configurations are automatically loaded with application properties if you are using spring boot.It would be needed only if additional configurations are required or if modifying an existing configuration programatically.
I guess,you do not need either of them for this job,that is ,you could always use this and not set configuration to get sessionfactory :
#Autowired
private EntityManagerFactory entityManagerFactory;
#Bean
public SessionFactory getSessionFactory() {
if (entityManagerFactory.unwrap(SessionFactory.class) == null) {
throw new NullPointerException("Not a hibernate factory exception");
}
return entityManagerFactory.unwrap(SessionFactory.class);
}
This way , your configurations are loaded automatically and you get your sessionfactory.
Hope this helps.

Resources