Showing posts with label Hibernate. Show all posts
Showing posts with label Hibernate. Show all posts

Thursday, May 19, 2022

get vs load in hibernate

get() vs load() in hibernate

n plus1 problem in hibernate

 N+1 problem in hibernate ?

The N+1 query problem is occur when 1 query to retrieve the parent entity and N queries to retrieve the child entities.

Solution : To Solve this isuue we can use OneToMany mapping in hibernate using Lazy loading.

Wednesday, October 16, 2019

Common Hibernate Exceptions


  • LazyInitialisationException
  • OptimisticLockException
  • Org.hibernate.AnnotationExceptio: Unknown Id.generator
  • QuerySyntaxException:Table is not mapped
  • Org.hibernate.persistObjectException:detached entity passed to persist
  • StaleObjectStateException
  • Org.hibernate.NonUniqueObjectException

Wednesday, July 3, 2019

Spring Boot Multiple Datasources Configuration

Spring Boot With Multiple Datasources Configuration

In this article we will discuss, how to configure multiple data sources with Spring Boot using Spring Data.
for this we need to create two configuration file for two database and need to do below.
  • DataSource configuration
  • EntityManagerFactory configuration
  • TransactionManager configuration
See below complete example.
Project structure.


Add dependencies in pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
						http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>in.javaiq</groupId>
	<artifactId>SpringBoot-Multiple-Datasources</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>SpringBoot-Multiple-Datasources</name>
	<description>Spring Boot Multiple Datasources With Spring Data</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.1.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		<dependency>
			<groupId>javax.validation</groupId>
			<artifactId>validation-api</artifactId>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<optional>true</optional>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>
Add below in application.properties here we are using two database company_db and employee_db using MYSQL database. As i have only MYSQL on my local. you can also use different database in same way.
# For Datasources-1
spring.datasource.company.url=jdbc:mysql://localhost:3306/company_db
spring.datasource.company.jdbcUrl=${spring.datasource.company.url}
spring.datasource.company.username=root
spring.datasource.company.password=root
spring.datasource.company.platform=mysql
spring.datasource.company.driverClassName = com.mysql.jdbc.Driver

# For Datasources-2
spring.datasource.employee.url=jdbc:mysql://localhost:3306/employee_db
spring.datasource.employee.jdbcUrl=${spring.datasource.employee.url}
spring.datasource.employee.username=root
spring.datasource.employee.password=root
spring.datasource.employee.platform=mysql
spring.datasource.employee.driverClassName = com.mysql.jdbc.Driver

spring.jpa.hibernate.ddl-auto=update
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
Create Model (JPA Entities) : Company.java and Employee.java
package in.javaiq.company.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "company")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Company {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private int id;

	@Column(nullable = false)
	private String name;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Company() {

	}

	public Company(String name) {
		super();
		this.name = name;
	}

	public Company(int id, String name) {
		super();
		this.id = id;
		this.name = name;
	}

	@Override
	public String toString() {
		return "Company [id=" + id + ", name=" + name + "]";
	}

}
package in.javaiq.employee.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "employees")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer id;

	@Column(nullable = false)
	private String name;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Employee() {

	}

	public Employee(String name) {
		super();
		this.name = name;
	}

	public Employee(Integer id, String name) {
		super();
		this.id = id;
		this.name = name;
	}

	@Override
	public String toString() {
		return "Employee [id=" + id + ", name=" + name + "]";
	}

}
Let's Create the JPA repositories for Company and Employee entities. This is used by Spring Data JPA to store data in a relational database. 
Create Repository : EmployeeRepository.java and EmployeeRepository.java
package in.javaiq.company.repo;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import in.javaiq.company.model.Company;

@Repository
public interface CompanyRepository extends CrudRepository<Company, Integer> {

}
package in.javaiq.employee.repo;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import in.javaiq.employee.model.Employee;

@Repository
public interface EmployeeRepository extends CrudRepository<Employee, Integer> {

}
Create two Spring db configuration classes who are responsible to create table and read/write from related datasourses.
Create Configuration classes : CompanyDBConfig.java and EmployeeDBConfig.java
package in.javaiq.config;

import java.util.HashMap;
import java.util.Map;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
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;

@Configuration
@EnableJpaRepositories(basePackages = "in.javaiq.company.repo", entityManagerFactoryRef = "companyEntityManagerFactory", transactionManagerRef = "companyTransactionManager")
public class CompanyDBConfig {

	@Bean(name = "companyDataSource")
	@ConfigurationProperties(prefix = "spring.datasource.company")
	public DataSource customerDataSource() {
		return DataSourceBuilder.create().build();
	}

	@Bean(name = "companyEntityManagerFactory")
	public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
			@Qualifier("companyDataSource") DataSource dataSource) {
		Map<String, Object> properties = new HashMap<String, Object>();
		// properties.put("hibernate.hbm2ddl.auto", "update");
		// properties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
		return builder.dataSource(dataSource).properties(properties).packages("in.javaiq.company.model")
				.persistenceUnit("db1").build();
	}

	@Bean(name = "companyTransactionManager")
	public PlatformTransactionManager customerTransactionManager(
			@Qualifier("companyEntityManagerFactory") EntityManagerFactory customerEntityManagerFactory) {
		return new JpaTransactionManager(customerEntityManagerFactory);
	}

}
package in.javaiq.config;

import java.util.HashMap;
import java.util.Map;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
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;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "in.javaiq.employee", entityManagerFactoryRef = "employeeEntityManagerFactory", transactionManagerRef = "employeeTransactionManager")
public class EmployeeDBConfig {
	@Primary
	@Bean(name = "employeeDataSource")
	@ConfigurationProperties(prefix = "spring.datasource.employee")
	public DataSource customerDataSource() {
		return DataSourceBuilder.create().build();
	}

	@Primary
	@Bean(name = "employeeEntityManagerFactory")
	public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
			@Qualifier("employeeDataSource") DataSource dataSource) {
		Map<String, Object> properties = new HashMap<String, Object>();
		// properties.put("hibernate.hbm2ddl.auto", "update");
		// properties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
		return builder.dataSource(dataSource).properties(properties).packages("in.javaiq.employee.model")
				.persistenceUnit("db2").build();
	}

	@Primary
	@Bean(name = "employeeTransactionManager")
	public PlatformTransactionManager customerTransactionManager(
			@Qualifier("employeeEntityManagerFactory") EntityManagerFactory customerEntityManagerFactory) {
		return new JpaTransactionManager(customerEntityManagerFactory);
	}
}
Create SpringBootMultipleDatasourcesApplication.java.
package in.javaiq;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import in.javaiq.company.model.Company;
import in.javaiq.company.repo.CompanyRepository;
import in.javaiq.employee.model.Employee;
import in.javaiq.employee.repo.EmployeeRepository;

@SpringBootApplication
@RestController
public class SpringBootMultipleDatasourcesApplication {

	@Autowired
	private CompanyRepository companyRepository;

	@Autowired
	private EmployeeRepository employeeRepository;

	@PostConstruct
	public void saveData() {
		;
		companyRepository
				.saveAll(Stream.of(new Company("Company-1"), new Company("Company-2")).collect(Collectors.toList()));
		employeeRepository.saveAll(
				Stream.of(new Employee("Employee-1"), new Employee("Employee-2")).collect(Collectors.toList()));
	}

	@GetMapping("/getCompanyList")
	public List<Company> getAllCompanys() {
		List<Company> companyes = (List<Company>) companyRepository.findAll();
		return companyes;

	}

	@GetMapping("/getEmployeeList")
	public List<Employee> getAllEmployees() {
		List<Employee> employeess = (List<Employee>) employeeRepository.findAll();
		return employeess;

	}

	public static void main(String[] args) {
		SpringApplication.run(SpringBootMultipleDatasourcesApplication.class, args);
	}

}
Note:- In this article you can see only two confugrations classes files are added than using one datasourses in spring boot.

Wednesday, June 26, 2019

Hibernate Envers


Many To Many Mapping Example In Hibernate


One To Many Mapping Example In Hibernate


One To One Mapping Example In Hibernate


Inheritance In Hibernate


Association In Hibernate


Fetching Strategies In Hibernate


Pessimistic Locking Example In Hibernate

Comming soon....

Optimistic Locking Example In Hibernate

Comming soon..

Locking In Hibernate

Comming soon...

N+1 Problem In Hibernate