JAVA-4 : added new module hibernate-enterprise
This commit is contained in:
parent
592df829e6
commit
074dd3e986
|
@ -0,0 +1,13 @@
|
||||||
|
## Hibernate 5
|
||||||
|
|
||||||
|
This module contains articles about Hibernate 5.
|
||||||
|
|
||||||
|
### Relevant articles:
|
||||||
|
|
||||||
|
- [Introduction to Hibernate Spatial](http://www.baeldung.com/hibernate-spatial)
|
||||||
|
- [A Guide to Multitenancy in Hibernate 5](http://www.baeldung.com/hibernate-5-multitenancy)
|
||||||
|
- [Hibernate Aggregate Functions](https://www.baeldung.com/hibernate-aggregate-functions)
|
||||||
|
- [Common Hibernate Exceptions](https://www.baeldung.com/hibernate-exceptions)
|
||||||
|
- [Hibernate Error “Not all named parameters have been set”](https://www.baeldung.com/hibernate-error-named-parameters-not-set)
|
||||||
|
- [FetchMode in Hibernate](https://www.baeldung.com/hibernate-fetchmode)
|
||||||
|
- [Various Logging Levels in Hibernate](https://www.baeldung.com/hibernate-logging-levels)
|
|
@ -0,0 +1,76 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>hibernate5-enterprise</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>hibernate5-enterprise</name>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>persistence-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate</groupId>
|
||||||
|
<artifactId>hibernate-core</artifactId>
|
||||||
|
<version>${hibernate.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${assertj-core.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
<version>${h2.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate</groupId>
|
||||||
|
<artifactId>hibernate-spatial</artifactId>
|
||||||
|
<version>${hibernate.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.opengeo</groupId>
|
||||||
|
<artifactId>geodb</artifactId>
|
||||||
|
<version>${geodb.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<version>${mysql.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.vorburger.mariaDB4j</groupId>
|
||||||
|
<artifactId>mariaDB4j</artifactId>
|
||||||
|
<version>${mariaDB4j.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate</groupId>
|
||||||
|
<artifactId>hibernate-testing</artifactId>
|
||||||
|
<version>${hibernate.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>geodb-repo</id>
|
||||||
|
<name>GeoDB repository</name>
|
||||||
|
<url>http://repo.boundlessgeo.com/main/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<hibernate.version>5.3.7.Final</hibernate.version>
|
||||||
|
<mysql.version>6.0.6</mysql.version>
|
||||||
|
<mariaDB4j.version>2.2.3</mariaDB4j.version>
|
||||||
|
<assertj-core.version>3.8.0</assertj-core.version>
|
||||||
|
<geodb.version>0.9</geodb.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,72 @@
|
||||||
|
package com.baeldung.hibernate;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.hibernate.boot.Metadata;
|
||||||
|
import org.hibernate.boot.MetadataSources;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
|
|
||||||
|
import com.baeldung.hibernate.pojo.PointEntity;
|
||||||
|
import com.baeldung.hibernate.pojo.PolygonEntity;
|
||||||
|
import com.baeldung.hibernate.pojo.Student;
|
||||||
|
|
||||||
|
public class HibernateUtil {
|
||||||
|
private static String PROPERTY_FILE_NAME;
|
||||||
|
|
||||||
|
public static SessionFactory getSessionFactory() throws IOException {
|
||||||
|
return getSessionFactory(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SessionFactory getSessionFactory(String propertyFileName) throws IOException {
|
||||||
|
PROPERTY_FILE_NAME = propertyFileName;
|
||||||
|
ServiceRegistry serviceRegistry = configureServiceRegistry();
|
||||||
|
return makeSessionFactory(serviceRegistry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SessionFactory getSessionFactoryByProperties(Properties properties) throws IOException {
|
||||||
|
ServiceRegistry serviceRegistry = configureServiceRegistry(properties);
|
||||||
|
return makeSessionFactory(serviceRegistry);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SessionFactory makeSessionFactory(ServiceRegistry serviceRegistry) {
|
||||||
|
MetadataSources metadataSources = new MetadataSources(serviceRegistry);
|
||||||
|
|
||||||
|
metadataSources.addPackage("com.baeldung.hibernate.pojo");
|
||||||
|
metadataSources.addAnnotatedClass(Student.class);
|
||||||
|
metadataSources.addAnnotatedClass(PointEntity.class);
|
||||||
|
metadataSources.addAnnotatedClass(PolygonEntity.class);
|
||||||
|
|
||||||
|
Metadata metadata = metadataSources.getMetadataBuilder()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return metadata.getSessionFactoryBuilder()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ServiceRegistry configureServiceRegistry() throws IOException {
|
||||||
|
return configureServiceRegistry(getProperties());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ServiceRegistry configureServiceRegistry(Properties properties) throws IOException {
|
||||||
|
return new StandardServiceRegistryBuilder().applySettings(properties)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Properties getProperties() throws IOException {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
URL propertiesURL = Thread.currentThread()
|
||||||
|
.getContextClassLoader()
|
||||||
|
.getResource(StringUtils.defaultString(PROPERTY_FILE_NAME, "hibernate.properties"));
|
||||||
|
try (FileInputStream inputStream = new FileInputStream(propertiesURL.getFile())) {
|
||||||
|
properties.load(inputStream);
|
||||||
|
}
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.baeldung.hibernate;
|
||||||
|
|
||||||
|
public class UnsupportedTenancyException extends Exception {
|
||||||
|
public UnsupportedTenancyException (String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.baeldung.hibernate.exception;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class EntityWithNoId {
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package com.baeldung.hibernate.exception;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.hibernate.boot.Metadata;
|
||||||
|
import org.hibernate.boot.MetadataSources;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
|
|
||||||
|
public class HibernateUtil {
|
||||||
|
private static SessionFactory sessionFactory;
|
||||||
|
private static String PROPERTY_FILE_NAME;
|
||||||
|
|
||||||
|
public static SessionFactory getSessionFactory() throws IOException {
|
||||||
|
return getSessionFactory(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SessionFactory getSessionFactory(String propertyFileName)
|
||||||
|
throws IOException {
|
||||||
|
PROPERTY_FILE_NAME = propertyFileName;
|
||||||
|
if (sessionFactory == null) {
|
||||||
|
ServiceRegistry serviceRegistry = configureServiceRegistry();
|
||||||
|
sessionFactory = makeSessionFactory(serviceRegistry);
|
||||||
|
}
|
||||||
|
return sessionFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SessionFactory makeSessionFactory(
|
||||||
|
ServiceRegistry serviceRegistry) {
|
||||||
|
MetadataSources metadataSources = new MetadataSources(serviceRegistry);
|
||||||
|
metadataSources.addAnnotatedClass(Product.class);
|
||||||
|
Metadata metadata = metadataSources.getMetadataBuilder()
|
||||||
|
.build();
|
||||||
|
return metadata.getSessionFactoryBuilder()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ServiceRegistry configureServiceRegistry()
|
||||||
|
throws IOException {
|
||||||
|
Properties properties = getProperties();
|
||||||
|
return new StandardServiceRegistryBuilder().applySettings(properties)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Properties getProperties() throws IOException {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
URL propertiesURL = Thread.currentThread()
|
||||||
|
.getContextClassLoader()
|
||||||
|
.getResource(StringUtils.defaultString(PROPERTY_FILE_NAME,
|
||||||
|
"hibernate-exception.properties"));
|
||||||
|
try (FileInputStream inputStream = new FileInputStream(
|
||||||
|
propertiesURL.getFile())) {
|
||||||
|
properties.load(inputStream);
|
||||||
|
}
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.baeldung.hibernate.exception;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Product {
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Column(nullable=false)
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
package com.baeldung.hibernate.logging;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Employee {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.SEQUENCE)
|
||||||
|
private long id;
|
||||||
|
|
||||||
|
private String employeeNumber;
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Employee() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Employee(String name, String employeeNumber) {
|
||||||
|
this.name = name;
|
||||||
|
this.employeeNumber = employeeNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmployeeNumber() {
|
||||||
|
return employeeNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmployeeNumber(String employeeNumber) {
|
||||||
|
this.employeeNumber = employeeNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.baeldung.hibernate.pojo;
|
||||||
|
|
||||||
|
import com.vividsolutions.jts.geom.Point;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class PointEntity {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(columnDefinition="BINARY(2048)")
|
||||||
|
private Point point;
|
||||||
|
|
||||||
|
public PointEntity() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Point getPoint() {
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPoint(Point point) {
|
||||||
|
this.point = point;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "PointEntity{" + "id=" + id + ", point=" + point + '}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.baeldung.hibernate.pojo;
|
||||||
|
|
||||||
|
import com.vividsolutions.jts.geom.Polygon;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class PolygonEntity {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private Polygon polygon;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Polygon getPolygon() {
|
||||||
|
return polygon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPolygon(Polygon polygon) {
|
||||||
|
this.polygon = polygon;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "PolygonEntity{" + "id=" + id + ", polygon=" + polygon + '}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.baeldung.hibernate.pojo;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Student {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.SEQUENCE)
|
||||||
|
private long studentId;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private int age;
|
||||||
|
|
||||||
|
public Student() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Student(String name, int age) {
|
||||||
|
this.name = name;
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getStudentId() {
|
||||||
|
return studentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStudentId(long studentId) {
|
||||||
|
this.studentId = studentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAge() {
|
||||||
|
return age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAge(int age) {
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.baeldung.hibernateparameters;
|
||||||
|
|
||||||
|
public class Event {
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
public Event() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Event(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
|
||||||
|
version="2.0">
|
||||||
|
<persistence-unit name="com.baeldung.movie_catalog">
|
||||||
|
<description>Hibernate EntityManager Demo</description>
|
||||||
|
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||||
|
<properties>
|
||||||
|
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
|
||||||
|
<property name="hibernate.hbm2ddl.auto" value="update"/>
|
||||||
|
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
|
||||||
|
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/moviecatalog"/>
|
||||||
|
<property name="javax.persistence.jdbc.user" value="root"/>
|
||||||
|
<property name="javax.persistence.jdbc.password" value="root"/>
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
|
</persistence>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE hibernate-mapping PUBLIC
|
||||||
|
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||||
|
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||||
|
|
||||||
|
<hibernate-mapping package="com.baeldung.hibernateparameters">
|
||||||
|
|
||||||
|
<class name="Event" table="EVENTS">
|
||||||
|
<id name="id" column="EVENT_ID">
|
||||||
|
<generator class="increment"/>
|
||||||
|
</id>
|
||||||
|
<property name="title"/>
|
||||||
|
</class>
|
||||||
|
|
||||||
|
</hibernate-mapping>
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<!DOCTYPE hibernate-configuration PUBLIC
|
||||||
|
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
|
||||||
|
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
|
||||||
|
|
||||||
|
<hibernate-configuration>
|
||||||
|
|
||||||
|
<session-factory>
|
||||||
|
<property name="connection.driver_class">org.h2.Driver</property>
|
||||||
|
<property name="connection.url">jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1</property>
|
||||||
|
<property name="connection.username">sa</property>
|
||||||
|
<property name="connection.password"/>
|
||||||
|
|
||||||
|
<property name="connection.pool_size">1</property>
|
||||||
|
|
||||||
|
<property name="dialect">org.hibernate.dialect.H2Dialect</property>
|
||||||
|
|
||||||
|
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
|
||||||
|
|
||||||
|
<property name="hibernate.generate_statistics">true</property>
|
||||||
|
|
||||||
|
<property name="hbm2ddl.auto">create</property>
|
||||||
|
|
||||||
|
<mapping class="com.baeldung.hibernate.logging.Employee"/>
|
||||||
|
</session-factory>
|
||||||
|
|
||||||
|
</hibernate-configuration>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<!DOCTYPE hibernate-configuration PUBLIC
|
||||||
|
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
|
||||||
|
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
|
||||||
|
|
||||||
|
<hibernate-configuration>
|
||||||
|
|
||||||
|
<session-factory>
|
||||||
|
<property name="connection.driver_class">org.h2.Driver</property>
|
||||||
|
<property name="connection.url">jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1</property>
|
||||||
|
<property name="connection.username">sa</property>
|
||||||
|
<property name="connection.password"/>
|
||||||
|
|
||||||
|
<property name="connection.pool_size">1</property>
|
||||||
|
|
||||||
|
<property name="dialect">org.hibernate.dialect.H2Dialect</property>
|
||||||
|
|
||||||
|
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
|
||||||
|
|
||||||
|
<property name="show_sql">true</property>
|
||||||
|
|
||||||
|
<property name="hbm2ddl.auto">create</property>
|
||||||
|
|
||||||
|
<mapping resource="com/baeldung/hibernateparameters/Event.hbm.xml"/>
|
||||||
|
|
||||||
|
</session-factory>
|
||||||
|
|
||||||
|
</hibernate-configuration>
|
|
@ -0,0 +1,10 @@
|
||||||
|
CREATE ALIAS UPDATE_EMPLOYEE_DESIGNATION AS $$
|
||||||
|
import java.sql.CallableStatement;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
@CODE
|
||||||
|
void updateEmployeeDesignation(final Connection conn, final String employeeNumber, final String title) throws SQLException {
|
||||||
|
CallableStatement updateStatement = conn.prepareCall("update deptemployee set title = '" + title + "' where employeeNumber = '" + employeeNumber + "'");
|
||||||
|
updateStatement.execute();
|
||||||
|
}
|
||||||
|
$$;
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||||
|
</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
|
@ -0,0 +1,161 @@
|
||||||
|
package com.baeldung.hibernate;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import javax.persistence.Query;
|
||||||
|
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.Transaction;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.hibernate.pojo.PointEntity;
|
||||||
|
import com.baeldung.hibernate.pojo.PolygonEntity;
|
||||||
|
import com.vividsolutions.jts.geom.Coordinate;
|
||||||
|
import com.vividsolutions.jts.geom.Geometry;
|
||||||
|
import com.vividsolutions.jts.geom.Point;
|
||||||
|
import com.vividsolutions.jts.geom.Polygon;
|
||||||
|
import com.vividsolutions.jts.io.ParseException;
|
||||||
|
import com.vividsolutions.jts.io.WKTReader;
|
||||||
|
import com.vividsolutions.jts.util.GeometricShapeFactory;
|
||||||
|
|
||||||
|
import geodb.GeoDB;
|
||||||
|
|
||||||
|
public class HibernateSpatialIntegrationTest {
|
||||||
|
|
||||||
|
private Session session;
|
||||||
|
private Transaction transaction;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws IOException {
|
||||||
|
session = HibernateUtil.getSessionFactory("hibernate-spatial.properties")
|
||||||
|
.openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
session.doWork(conn -> { GeoDB.InitGeoDB(conn); });
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
transaction.rollback();
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldConvertWktToGeometry() throws ParseException {
|
||||||
|
Geometry geometry = wktToGeometry("POINT (2 5)");
|
||||||
|
assertEquals("Point", geometry.getGeometryType());
|
||||||
|
assertTrue(geometry instanceof Point);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldInsertAndSelectPoints() throws ParseException {
|
||||||
|
PointEntity entity = new PointEntity();
|
||||||
|
entity.setPoint((Point) wktToGeometry("POINT (1 1)"));
|
||||||
|
|
||||||
|
session.persist(entity);
|
||||||
|
PointEntity fromDb = session.find(PointEntity.class, entity.getId());
|
||||||
|
assertEquals("POINT (1 1)", fromDb.getPoint().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldSelectDisjointPoints() throws ParseException {
|
||||||
|
insertPoint("POINT (1 2)");
|
||||||
|
insertPoint("POINT (3 4)");
|
||||||
|
insertPoint("POINT (5 6)");
|
||||||
|
|
||||||
|
Point point = (Point) wktToGeometry("POINT (3 4)");
|
||||||
|
Query query = session.createQuery("select p from PointEntity p "
|
||||||
|
+ "where disjoint(p.point, :point) = true", PointEntity.class);
|
||||||
|
query.setParameter("point", point);
|
||||||
|
assertEquals("POINT (1 2)", ((PointEntity) query.getResultList().get(0)).getPoint().toString());
|
||||||
|
assertEquals("POINT (5 6)", ((PointEntity) query.getResultList().get(1)).getPoint().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldSelectAllPointsWithinPolygon() throws ParseException {
|
||||||
|
insertPoint("POINT (1 1)");
|
||||||
|
insertPoint("POINT (1 2)");
|
||||||
|
insertPoint("POINT (3 4)");
|
||||||
|
insertPoint("POINT (5 6)");
|
||||||
|
|
||||||
|
Query query = session.createQuery("select p from PointEntity p where within(p.point, :area) = true",
|
||||||
|
PointEntity.class);
|
||||||
|
query.setParameter("area", wktToGeometry("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))"));
|
||||||
|
assertThat(query.getResultList().stream().map(p -> ((PointEntity) p).getPoint().toString()))
|
||||||
|
.containsOnly("POINT (1 1)", "POINT (1 2)", "POINT (3 4)");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldSelectAllPointsWithinRadius() throws ParseException {
|
||||||
|
insertPoint("POINT (1 1)");
|
||||||
|
insertPoint("POINT (1 2)");
|
||||||
|
insertPoint("POINT (3 4)");
|
||||||
|
insertPoint("POINT (5 6)");
|
||||||
|
|
||||||
|
Query query = session.createQuery("select p from PointEntity p where within(p.point, :circle) = true",
|
||||||
|
PointEntity.class);
|
||||||
|
query.setParameter("circle", createCircle(0.0, 0.0, 5));
|
||||||
|
|
||||||
|
assertThat(query.getResultList().stream().map(p -> ((PointEntity) p).getPoint().toString()))
|
||||||
|
.containsOnly("POINT (1 1)", "POINT (1 2)");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldSelectAdjacentPolygons() throws ParseException {
|
||||||
|
insertPolygon("POLYGON ((0 0, 0 5, 5 5, 5 0, 0 0))");
|
||||||
|
insertPolygon("POLYGON ((3 0, 3 5, 8 5, 8 0, 3 0))");
|
||||||
|
insertPolygon("POLYGON ((2 2, 3 1, 2 5, 4 3, 3 3, 2 2))");
|
||||||
|
|
||||||
|
Query query = session.createQuery("select p from PolygonEntity p where touches(p.polygon, :polygon) = true",
|
||||||
|
PolygonEntity.class);
|
||||||
|
query.setParameter("polygon", wktToGeometry("POLYGON ((5 5, 5 10, 10 10, 10 5, 5 5))"));
|
||||||
|
assertThat(query.getResultList().stream().map(p -> ((PolygonEntity) p).getPolygon().toString()))
|
||||||
|
.containsOnly("POLYGON ((0 0, 0 5, 5 5, 5 0, 0 0))", "POLYGON ((3 0, 3 5, 8 5, 8 0, 3 0))");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void insertPoint(String point) throws ParseException {
|
||||||
|
PointEntity entity = new PointEntity();
|
||||||
|
entity.setPoint((Point) wktToGeometry(point));
|
||||||
|
session.persist(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void insertPolygon(String polygon) throws ParseException {
|
||||||
|
PolygonEntity entity = new PolygonEntity();
|
||||||
|
entity.setPolygon((Polygon) wktToGeometry(polygon));
|
||||||
|
session.persist(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Geometry wktToGeometry(String wellKnownText) throws ParseException {
|
||||||
|
WKTReader fromText = new WKTReader();
|
||||||
|
Geometry geom = null;
|
||||||
|
geom = fromText.read(wellKnownText);
|
||||||
|
return geom;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Geometry createCircle(double x, double y, double radius) {
|
||||||
|
GeometricShapeFactory shapeFactory = new GeometricShapeFactory();
|
||||||
|
shapeFactory.setNumPoints(32);
|
||||||
|
shapeFactory.setCentre(new Coordinate(x, y));
|
||||||
|
shapeFactory.setSize(radius * 2);
|
||||||
|
return shapeFactory.createCircle();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Properties getProperties(String propertyFile) throws IOException {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
URL propertiesURL = Thread.currentThread()
|
||||||
|
.getContextClassLoader()
|
||||||
|
.getResource(propertyFile);
|
||||||
|
try (FileInputStream inputStream = new FileInputStream(propertiesURL.getFile())) {
|
||||||
|
properties.load(inputStream);
|
||||||
|
}
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
package com.baeldung.hibernate.aggregatefunctions;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.Transaction;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.hibernate.HibernateUtil;
|
||||||
|
import com.baeldung.hibernate.pojo.Student;
|
||||||
|
|
||||||
|
public class AggregateFunctionsIntegrationTest {
|
||||||
|
|
||||||
|
private static Session session;
|
||||||
|
private static Transaction transaction;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static final void setup() throws HibernateException, IOException {
|
||||||
|
session = HibernateUtil.getSessionFactory()
|
||||||
|
.openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
Student jonas = new Student("Jonas", 22);
|
||||||
|
session.save(jonas);
|
||||||
|
|
||||||
|
Student sally = new Student("Sally", 20);
|
||||||
|
session.save(sally);
|
||||||
|
|
||||||
|
Student simon = new Student("Simon", 25);
|
||||||
|
session.save(simon);
|
||||||
|
|
||||||
|
Student raven = new Student("Raven", 21);
|
||||||
|
session.save(raven);
|
||||||
|
|
||||||
|
Student sam = new Student("Sam", 23);
|
||||||
|
session.save(sam);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static final void teardown() {
|
||||||
|
if (session != null) {
|
||||||
|
transaction.rollback();
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenMaxAge_ThenReturnValue() {
|
||||||
|
int maxAge = (int) session.createQuery("SELECT MAX(age) from Student")
|
||||||
|
.getSingleResult();
|
||||||
|
assertThat(maxAge).isEqualTo(25);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenMinAge_ThenReturnValue() {
|
||||||
|
int minAge = (int) session.createQuery("SELECT MIN(age) from Student")
|
||||||
|
.getSingleResult();
|
||||||
|
assertThat(minAge).isEqualTo(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAverageAge_ThenReturnValue() {
|
||||||
|
Double avgAge = (Double) session.createQuery("SELECT AVG(age) from Student")
|
||||||
|
.getSingleResult();
|
||||||
|
assertThat(avgAge).isEqualTo(22.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCountAll_ThenReturnValue() {
|
||||||
|
Long totalStudents = (Long) session.createQuery("SELECT COUNT(*) from Student")
|
||||||
|
.getSingleResult();
|
||||||
|
assertThat(totalStudents).isEqualTo(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSumOfAllAges_ThenReturnValue() {
|
||||||
|
Long sumOfAllAges = (Long) session.createQuery("SELECT SUM(age) from Student")
|
||||||
|
.getSingleResult();
|
||||||
|
assertThat(sumOfAllAges).isEqualTo(111);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,425 @@
|
||||||
|
package com.baeldung.hibernate.exception;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.isA;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.persistence.OptimisticLockException;
|
||||||
|
import javax.persistence.PersistenceException;
|
||||||
|
|
||||||
|
import org.hibernate.AnnotationException;
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.NonUniqueObjectException;
|
||||||
|
import org.hibernate.PropertyValueException;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.hibernate.StaleObjectStateException;
|
||||||
|
import org.hibernate.StaleStateException;
|
||||||
|
import org.hibernate.Transaction;
|
||||||
|
import org.hibernate.TransactionException;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.cfg.Configuration;
|
||||||
|
import org.hibernate.exception.ConstraintViolationException;
|
||||||
|
import org.hibernate.exception.DataException;
|
||||||
|
import org.hibernate.exception.SQLGrammarException;
|
||||||
|
import org.hibernate.query.NativeQuery;
|
||||||
|
import org.hibernate.tool.schema.spi.CommandAcceptanceException;
|
||||||
|
import org.hibernate.tool.schema.spi.SchemaManagementException;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class HibernateExceptionUnitTest {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory
|
||||||
|
.getLogger(HibernateExceptionUnitTest.class);
|
||||||
|
private SessionFactory sessionFactory;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws IOException {
|
||||||
|
sessionFactory = HibernateUtil.getSessionFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public ExpectedException thrown = ExpectedException.none();
|
||||||
|
|
||||||
|
private Configuration getConfiguration() {
|
||||||
|
Configuration cfg = new Configuration();
|
||||||
|
cfg.setProperty(AvailableSettings.DIALECT,
|
||||||
|
"org.hibernate.dialect.H2Dialect");
|
||||||
|
cfg.setProperty(AvailableSettings.HBM2DDL_AUTO, "none");
|
||||||
|
cfg.setProperty(AvailableSettings.DRIVER, "org.h2.Driver");
|
||||||
|
cfg.setProperty(AvailableSettings.URL,
|
||||||
|
"jdbc:h2:mem:myexceptiondb2;DB_CLOSE_DELAY=-1");
|
||||||
|
cfg.setProperty(AvailableSettings.USER, "sa");
|
||||||
|
cfg.setProperty(AvailableSettings.PASS, "");
|
||||||
|
return cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenQueryExecutedWithUnmappedEntity_thenMappingException() {
|
||||||
|
thrown.expectCause(isA(MappingException.class));
|
||||||
|
thrown.expectMessage("Unknown entity: java.lang.String");
|
||||||
|
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
NativeQuery<String> query = session
|
||||||
|
.createNativeQuery("select name from PRODUCT", String.class);
|
||||||
|
query.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
public void whenQueryExecuted_thenOK() {
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
NativeQuery query = session
|
||||||
|
.createNativeQuery("select name from PRODUCT");
|
||||||
|
List results = query.getResultList();
|
||||||
|
assertNotNull(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEntityWithoutId_whenSessionFactoryCreated_thenAnnotationException() {
|
||||||
|
thrown.expect(AnnotationException.class);
|
||||||
|
thrown.expectMessage("No identifier specified for entity");
|
||||||
|
|
||||||
|
Configuration cfg = getConfiguration();
|
||||||
|
cfg.addAnnotatedClass(EntityWithNoId.class);
|
||||||
|
cfg.buildSessionFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMissingTable_whenSchemaValidated_thenSchemaManagementException() {
|
||||||
|
thrown.expect(SchemaManagementException.class);
|
||||||
|
thrown.expectMessage("Schema-validation: missing table");
|
||||||
|
|
||||||
|
Configuration cfg = getConfiguration();
|
||||||
|
cfg.setProperty(AvailableSettings.HBM2DDL_AUTO, "validate");
|
||||||
|
cfg.addAnnotatedClass(Product.class);
|
||||||
|
cfg.buildSessionFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenWrongDialectSpecified_thenCommandAcceptanceException() {
|
||||||
|
thrown.expect(SchemaManagementException.class);
|
||||||
|
thrown.expectCause(isA(CommandAcceptanceException.class));
|
||||||
|
thrown.expectMessage("Halting on error : Error executing DDL");
|
||||||
|
|
||||||
|
Configuration cfg = getConfiguration();
|
||||||
|
cfg.setProperty(AvailableSettings.DIALECT,
|
||||||
|
"org.hibernate.dialect.MySQLDialect");
|
||||||
|
cfg.setProperty(AvailableSettings.HBM2DDL_AUTO, "update");
|
||||||
|
|
||||||
|
// This does not work due to hibernate bug
|
||||||
|
// cfg.setProperty(AvailableSettings.HBM2DDL_HALT_ON_ERROR,"true");
|
||||||
|
cfg.getProperties()
|
||||||
|
.put(AvailableSettings.HBM2DDL_HALT_ON_ERROR, true);
|
||||||
|
|
||||||
|
cfg.addAnnotatedClass(Product.class);
|
||||||
|
cfg.buildSessionFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMissingTable_whenEntitySaved_thenSQLGrammarException() {
|
||||||
|
thrown.expect(isA(PersistenceException.class));
|
||||||
|
thrown.expectCause(isA(SQLGrammarException.class));
|
||||||
|
thrown
|
||||||
|
.expectMessage("SQLGrammarException: could not prepare statement");
|
||||||
|
|
||||||
|
Configuration cfg = getConfiguration();
|
||||||
|
cfg.addAnnotatedClass(Product.class);
|
||||||
|
|
||||||
|
SessionFactory sessionFactory = cfg.buildSessionFactory();
|
||||||
|
Session session = null;
|
||||||
|
Transaction transaction = null;
|
||||||
|
try {
|
||||||
|
|
||||||
|
session = sessionFactory.openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
Product product = new Product();
|
||||||
|
product.setId(1);
|
||||||
|
product.setName("Product 1");
|
||||||
|
session.save(product);
|
||||||
|
transaction.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
rollbackTransactionQuietly(transaction);
|
||||||
|
throw (e);
|
||||||
|
} finally {
|
||||||
|
closeSessionQuietly(session);
|
||||||
|
closeSessionFactoryQuietly(sessionFactory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMissingTable_whenQueryExecuted_thenSQLGrammarException() {
|
||||||
|
thrown.expect(isA(PersistenceException.class));
|
||||||
|
thrown.expectCause(isA(SQLGrammarException.class));
|
||||||
|
thrown
|
||||||
|
.expectMessage("SQLGrammarException: could not prepare statement");
|
||||||
|
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
NativeQuery<Product> query = session.createNativeQuery(
|
||||||
|
"select * from NON_EXISTING_TABLE", Product.class);
|
||||||
|
query.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDuplicateIdSaved_thenConstraintViolationException() {
|
||||||
|
thrown.expect(isA(PersistenceException.class));
|
||||||
|
thrown.expectCause(isA(ConstraintViolationException.class));
|
||||||
|
thrown.expectMessage(
|
||||||
|
"ConstraintViolationException: could not execute statement");
|
||||||
|
|
||||||
|
Session session = null;
|
||||||
|
Transaction transaction = null;
|
||||||
|
|
||||||
|
for (int i = 1; i <= 2; i++) {
|
||||||
|
try {
|
||||||
|
session = sessionFactory.openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
Product product = new Product();
|
||||||
|
product.setId(1);
|
||||||
|
product.setName("Product " + i);
|
||||||
|
session.save(product);
|
||||||
|
transaction.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
rollbackTransactionQuietly(transaction);
|
||||||
|
throw (e);
|
||||||
|
} finally {
|
||||||
|
closeSessionQuietly(session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNotNullPropertyNotSet_whenEntityIdSaved_thenPropertyValueException() {
|
||||||
|
thrown.expect(isA(PropertyValueException.class));
|
||||||
|
thrown.expectMessage(
|
||||||
|
"not-null property references a null or transient value");
|
||||||
|
|
||||||
|
Session session = null;
|
||||||
|
Transaction transaction = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
session = sessionFactory.openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
Product product = new Product();
|
||||||
|
product.setId(1);
|
||||||
|
session.save(product);
|
||||||
|
transaction.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
rollbackTransactionQuietly(transaction);
|
||||||
|
throw (e);
|
||||||
|
} finally {
|
||||||
|
closeSessionQuietly(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenQueryWithDataTypeMismatch_WhenQueryExecuted_thenDataException() {
|
||||||
|
thrown.expectCause(isA(DataException.class));
|
||||||
|
thrown.expectMessage(
|
||||||
|
"org.hibernate.exception.DataException: could not prepare statement");
|
||||||
|
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
NativeQuery<Product> query = session.createNativeQuery(
|
||||||
|
"select * from PRODUCT where id='wrongTypeId'", Product.class);
|
||||||
|
query.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSessionContainingAnId_whenIdAssociatedAgain_thenNonUniqueObjectException() {
|
||||||
|
thrown.expect(isA(NonUniqueObjectException.class));
|
||||||
|
thrown.expectMessage(
|
||||||
|
"A different object with the same identifier value was already associated with the session");
|
||||||
|
|
||||||
|
Session session = null;
|
||||||
|
Transaction transaction = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
session = sessionFactory.openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
Product product1 = new Product();
|
||||||
|
product1.setId(1);
|
||||||
|
product1.setName("Product 1");
|
||||||
|
session.save(product1);
|
||||||
|
|
||||||
|
Product product2 = new Product();
|
||||||
|
product2.setId(1);
|
||||||
|
product2.setName("Product 2");
|
||||||
|
session.save(product2);
|
||||||
|
|
||||||
|
transaction.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
rollbackTransactionQuietly(transaction);
|
||||||
|
throw (e);
|
||||||
|
} finally {
|
||||||
|
closeSessionQuietly(session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDeletingADeletedObject_thenOptimisticLockException() {
|
||||||
|
thrown.expect(isA(OptimisticLockException.class));
|
||||||
|
thrown.expectMessage(
|
||||||
|
"Batch update returned unexpected row count from update");
|
||||||
|
thrown.expectCause(isA(StaleStateException.class));
|
||||||
|
|
||||||
|
Session session = null;
|
||||||
|
Transaction transaction = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
session = sessionFactory.openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
Product product1 = new Product();
|
||||||
|
product1.setId(12);
|
||||||
|
product1.setName("Product 12");
|
||||||
|
session.save(product1);
|
||||||
|
transaction.commit();
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
session = sessionFactory.openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
Product product2 = session.get(Product.class, 12);
|
||||||
|
session.createNativeQuery("delete from Product where id=12")
|
||||||
|
.executeUpdate();
|
||||||
|
// We need to refresh to fix the error.
|
||||||
|
// session.refresh(product2);
|
||||||
|
session.delete(product2);
|
||||||
|
transaction.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
rollbackTransactionQuietly(transaction);
|
||||||
|
throw (e);
|
||||||
|
} finally {
|
||||||
|
closeSessionQuietly(session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenUpdatingNonExistingObject_thenStaleStateException() {
|
||||||
|
thrown.expect(isA(OptimisticLockException.class));
|
||||||
|
thrown
|
||||||
|
.expectMessage("Row was updated or deleted by another transaction");
|
||||||
|
thrown.expectCause(isA(StaleObjectStateException.class));
|
||||||
|
|
||||||
|
Session session = null;
|
||||||
|
Transaction transaction = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
session = sessionFactory.openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
Product product1 = new Product();
|
||||||
|
product1.setId(15);
|
||||||
|
product1.setName("Product1");
|
||||||
|
session.update(product1);
|
||||||
|
transaction.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
rollbackTransactionQuietly(transaction);
|
||||||
|
throw (e);
|
||||||
|
} finally {
|
||||||
|
closeSessionQuietly(session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTxnMarkedRollbackOnly_whenCommitted_thenTransactionException() {
|
||||||
|
thrown.expect(isA(TransactionException.class));
|
||||||
|
|
||||||
|
Session session = null;
|
||||||
|
Transaction transaction = null;
|
||||||
|
try {
|
||||||
|
session = sessionFactory.openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
Product product1 = new Product();
|
||||||
|
product1.setId(15);
|
||||||
|
product1.setName("Product1");
|
||||||
|
session.save(product1);
|
||||||
|
transaction.setRollbackOnly();
|
||||||
|
|
||||||
|
transaction.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
rollbackTransactionQuietly(transaction);
|
||||||
|
throw (e);
|
||||||
|
} finally {
|
||||||
|
closeSessionQuietly(session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rollbackTransactionQuietly(Transaction transaction) {
|
||||||
|
if (transaction != null && transaction.isActive()) {
|
||||||
|
try {
|
||||||
|
transaction.rollback();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Exception while rolling back transaction", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void closeSessionQuietly(Session session) {
|
||||||
|
if (session != null) {
|
||||||
|
try {
|
||||||
|
session.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Exception while closing session", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void closeSessionFactoryQuietly(SessionFactory sessionFactory) {
|
||||||
|
if (sessionFactory != null) {
|
||||||
|
try {
|
||||||
|
sessionFactory.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Exception while closing sessionFactory", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenExistingEntity_whenIdUpdated_thenHibernateException() {
|
||||||
|
thrown.expect(isA(PersistenceException.class));
|
||||||
|
thrown.expectCause(isA(HibernateException.class));
|
||||||
|
thrown.expectMessage(
|
||||||
|
"identifier of an instance of com.baeldung.hibernate.exception.Product was altered");
|
||||||
|
|
||||||
|
Session session = null;
|
||||||
|
Transaction transaction = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
session = sessionFactory.openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
Product product1 = new Product();
|
||||||
|
product1.setId(222);
|
||||||
|
product1.setName("Product 222");
|
||||||
|
session.save(product1);
|
||||||
|
transaction.commit();
|
||||||
|
closeSessionQuietly(session);
|
||||||
|
|
||||||
|
session = sessionFactory.openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
Product product2 = session.get(Product.class, 222);
|
||||||
|
product2.setId(333);
|
||||||
|
session.save(product2);
|
||||||
|
|
||||||
|
transaction.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
rollbackTransactionQuietly(transaction);
|
||||||
|
throw (e);
|
||||||
|
} finally {
|
||||||
|
closeSessionQuietly(session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.baeldung.hibernate.logging;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.hibernate.boot.MetadataSources;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
import org.hibernate.query.Query;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.hibernate.logging.Employee;
|
||||||
|
|
||||||
|
public class HibernateLoggingIntegrationTest {
|
||||||
|
|
||||||
|
private SessionFactory sessionFactory;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws IOException {
|
||||||
|
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure("hibernate-logging.cfg.xml")
|
||||||
|
.build();
|
||||||
|
try {
|
||||||
|
sessionFactory = new MetadataSources(registry).buildMetadata()
|
||||||
|
.buildSessionFactory();
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
session.save(new Employee("John Smith", "001"));
|
||||||
|
session.getTransaction()
|
||||||
|
.commit();
|
||||||
|
session.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
fail(e);
|
||||||
|
StandardServiceRegistryBuilder.destroy(registry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAllEmployeesAreSelected_ThenSuccess() {
|
||||||
|
Query<Employee> query = sessionFactory.openSession().createQuery("from com.baeldung.hibernate.logging.Employee", Employee.class);
|
||||||
|
List<Employee> deptEmployees = query.list();
|
||||||
|
Employee deptEmployee = deptEmployees.get(0);
|
||||||
|
assertEquals("John Smith", deptEmployee.getName());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.baeldung.hibernate.multitenancy;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity(name = "Car")
|
||||||
|
@Table(name = "Car")
|
||||||
|
public class Car implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1015320564683423342L;
|
||||||
|
|
||||||
|
private String brand;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
public String getBrand() {
|
||||||
|
return brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBrand(String brand) {
|
||||||
|
this.brand = brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
package com.baeldung.hibernate.multitenancy;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.hibernate.Transaction;
|
||||||
|
import org.hibernate.boot.MetadataSources;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import com.baeldung.hibernate.multitenancy.database.TenantIdNames;
|
||||||
|
|
||||||
|
public abstract class MultitenancyIntegrationTest {
|
||||||
|
|
||||||
|
public abstract String getPropertyFile();
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private CurrentTenantIdentifierResolver currentTenantIdentifierResolver;
|
||||||
|
|
||||||
|
private SessionFactory sessionFactory;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() throws IOException {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
|
Mockito.when(currentTenantIdentifierResolver.validateExistingCurrentSessions())
|
||||||
|
.thenReturn(false);
|
||||||
|
|
||||||
|
Properties properties = getHibernateProperties();
|
||||||
|
properties.put(AvailableSettings.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolver);
|
||||||
|
|
||||||
|
sessionFactory = buildSessionFactory(properties);
|
||||||
|
|
||||||
|
initTenant(TenantIdNames.MYDB1);
|
||||||
|
initTenant(TenantIdNames.MYDB2);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initTenant(String tenantId) {
|
||||||
|
whenCurrentTenantIs(tenantId);
|
||||||
|
createCarTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void whenCurrentTenantIs(String tenantId) {
|
||||||
|
Mockito.when(currentTenantIdentifierResolver.resolveCurrentTenantIdentifier())
|
||||||
|
.thenReturn(tenantId);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void whenAddCar(String brand) {
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
Transaction tx = session.beginTransaction();
|
||||||
|
Car car = new Car();
|
||||||
|
car.setBrand(brand);
|
||||||
|
session.save(car);
|
||||||
|
tx.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void thenCarFound(String brand) {
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
assertNotNull(session.get(Car.class, brand));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void thenCarNotFound(String brand) {
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
assertNull(session.get(Car.class, brand));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
private void createCarTable() {
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
Transaction tx = session.beginTransaction();
|
||||||
|
session.createSQLQuery("drop table Car if exists")
|
||||||
|
.executeUpdate();
|
||||||
|
session.createSQLQuery("create table Car (brand varchar(255) primary key)")
|
||||||
|
.executeUpdate();
|
||||||
|
tx.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Properties getHibernateProperties() throws IOException {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.load(getClass().getResourceAsStream(getPropertyFile()));
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SessionFactory buildSessionFactory(Properties properties) {
|
||||||
|
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(properties)
|
||||||
|
.build();
|
||||||
|
MetadataSources metadataSources = new MetadataSources(serviceRegistry);
|
||||||
|
metadataSources.addAnnotatedClass(Car.class);
|
||||||
|
return metadataSources.buildMetadata()
|
||||||
|
.buildSessionFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.baeldung.hibernate.multitenancy.database;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.hibernate.multitenancy.MultitenancyIntegrationTest;
|
||||||
|
|
||||||
|
public class DatabaseApproachMultitenancyIntegrationTest extends MultitenancyIntegrationTest {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPropertyFile() {
|
||||||
|
return "/hibernate-database-multitenancy.properties";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDatabaseApproach_whenAddingEntries_thenOnlyAddedToConcreteDatabase() throws IOException {
|
||||||
|
whenCurrentTenantIs(TenantIdNames.MYDB1);
|
||||||
|
whenAddCar("myCar");
|
||||||
|
thenCarFound("myCar");
|
||||||
|
whenCurrentTenantIs(TenantIdNames.MYDB2);
|
||||||
|
thenCarNotFound("myCar");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.baeldung.hibernate.multitenancy.database;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
|
||||||
|
import org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider;
|
||||||
|
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class MapMultiTenantConnectionProvider extends AbstractMultiTenantConnectionProvider {
|
||||||
|
|
||||||
|
private final Map<String, ConnectionProvider> connectionProviderMap = new HashMap<>();
|
||||||
|
|
||||||
|
public MapMultiTenantConnectionProvider() throws IOException {
|
||||||
|
initConnectionProviderForTenant(TenantIdNames.MYDB1);
|
||||||
|
initConnectionProviderForTenant(TenantIdNames.MYDB2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ConnectionProvider getAnyConnectionProvider() {
|
||||||
|
return connectionProviderMap.values()
|
||||||
|
.iterator()
|
||||||
|
.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ConnectionProvider selectConnectionProvider(String tenantIdentifier) {
|
||||||
|
return connectionProviderMap.get(tenantIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initConnectionProviderForTenant(String tenantId) throws IOException {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.load(getClass().getResourceAsStream(String.format("/hibernate-database-%s.properties", tenantId)));
|
||||||
|
DriverManagerConnectionProviderImpl connectionProvider = new DriverManagerConnectionProviderImpl();
|
||||||
|
connectionProvider.configure(properties);
|
||||||
|
this.connectionProviderMap.put(tenantId, connectionProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package com.baeldung.hibernate.multitenancy.database;
|
||||||
|
|
||||||
|
public class TenantIdNames {
|
||||||
|
public static final String MYDB1 = "mydb1";
|
||||||
|
public static final String MYDB2 = "mydb2";
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.baeldung.hibernate.multitenancy.schema;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.hibernate.multitenancy.MultitenancyIntegrationTest;
|
||||||
|
import com.baeldung.hibernate.multitenancy.database.TenantIdNames;
|
||||||
|
|
||||||
|
public class SchemaApproachMultitenancyIntegrationTest extends MultitenancyIntegrationTest {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPropertyFile() {
|
||||||
|
return "/hibernate-schema-multitenancy.properties";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSchemaApproach_whenAddingEntries_thenOnlyAddedToConcreteSchema() throws IOException {
|
||||||
|
whenCurrentTenantIs(TenantIdNames.MYDB1);
|
||||||
|
whenAddCar("Ferrari");
|
||||||
|
thenCarFound("Ferrari");
|
||||||
|
whenCurrentTenantIs(TenantIdNames.MYDB2);
|
||||||
|
thenCarNotFound("Ferrari");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.baeldung.hibernate.multitenancy.schema;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
|
||||||
|
import org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider;
|
||||||
|
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class SchemaMultiTenantConnectionProvider extends AbstractMultiTenantConnectionProvider {
|
||||||
|
|
||||||
|
private final ConnectionProvider connectionProvider;
|
||||||
|
|
||||||
|
public SchemaMultiTenantConnectionProvider() throws IOException {
|
||||||
|
connectionProvider = initConnectionProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ConnectionProvider getAnyConnectionProvider() {
|
||||||
|
return connectionProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ConnectionProvider selectConnectionProvider(String tenantIdentifier) {
|
||||||
|
return connectionProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Connection getConnection(String tenantIdentifier) throws SQLException {
|
||||||
|
Connection connection = super.getConnection(tenantIdentifier);
|
||||||
|
connection.createStatement()
|
||||||
|
.execute(String.format("SET SCHEMA %s;", tenantIdentifier));
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConnectionProvider initConnectionProvider() throws IOException {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.load(getClass().getResourceAsStream("/hibernate-schema-multitenancy.properties"));
|
||||||
|
|
||||||
|
DriverManagerConnectionProviderImpl connectionProvider = new DriverManagerConnectionProviderImpl();
|
||||||
|
connectionProvider.configure(properties);
|
||||||
|
return connectionProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package com.baeldung.hibernate.multitenancy.schema;
|
||||||
|
|
||||||
|
public class TenantIdNames {
|
||||||
|
public static final String MYDB1 = "mydb1";
|
||||||
|
public static final String MYDB2 = "mydb2";
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
package com.baeldung.hibernateparameters;
|
||||||
|
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.hibernate.boot.MetadataSources;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
import org.hibernate.query.Query;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
|
||||||
|
public class NamedParameterUnitTest {
|
||||||
|
private SessionFactory sessionFactory;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
|
||||||
|
.configure()
|
||||||
|
.build();
|
||||||
|
try {
|
||||||
|
sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
session.save(new Event("Event 1"));
|
||||||
|
session.save(new Event("Event 2"));
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
fail(e);
|
||||||
|
StandardServiceRegistryBuilder.destroy(registry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
if (sessionFactory != null) {
|
||||||
|
sessionFactory.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenNamedParameterProvided_thenCorrect() {
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
Query<Event> query = session.createQuery("from Event E WHERE E.title = :eventTitle", Event.class);
|
||||||
|
|
||||||
|
// This binds the value "Event1" to the parameter :eventTitle
|
||||||
|
query.setParameter("eventTitle", "Event 1");
|
||||||
|
|
||||||
|
assertEquals(1, query.list().size());
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = org.hibernate.QueryException.class)
|
||||||
|
public void whenNamedParameterMissing_thenThrowsQueryException() {
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
Query<Event> query = session.createQuery("from Event E WHERE E.title = :eventTitle", Event.class);
|
||||||
|
|
||||||
|
try {
|
||||||
|
query.list();
|
||||||
|
fail("We are expecting an exception!");
|
||||||
|
} finally {
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
hibernate.multiTenancy=DATABASE
|
||||||
|
hibernate.multi_tenant_connection_provider=com.baeldung.hibernate.multitenancy.database.MapMultiTenantConnectionProvider
|
|
@ -0,0 +1,4 @@
|
||||||
|
hibernate.connection.driver_class=org.h2.Driver
|
||||||
|
hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1
|
||||||
|
hibernate.connection.username=sa
|
||||||
|
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
|
@ -0,0 +1,4 @@
|
||||||
|
hibernate.connection.driver_class=org.h2.Driver
|
||||||
|
hibernate.connection.url=jdbc:h2:mem:mydb2;DB_CLOSE_DELAY=-1
|
||||||
|
hibernate.connection.username=sa
|
||||||
|
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
|
@ -0,0 +1,16 @@
|
||||||
|
hibernate.connection.driver_class=org.h2.Driver
|
||||||
|
hibernate.connection.url=jdbc:h2:mem:myexceptiondb1;DB_CLOSE_DELAY=-1
|
||||||
|
hibernate.connection.username=sa
|
||||||
|
hibernate.connection.autocommit=true
|
||||||
|
jdbc.password=
|
||||||
|
|
||||||
|
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
||||||
|
hibernate.show_sql=true
|
||||||
|
hibernate.hbm2ddl.auto=create-drop
|
||||||
|
|
||||||
|
hibernate.c3p0.min_size=5
|
||||||
|
hibernate.c3p0.max_size=20
|
||||||
|
hibernate.c3p0.acquire_increment=5
|
||||||
|
hibernate.c3p0.timeout=1800
|
||||||
|
|
||||||
|
hibernate.transaction.factory_class=org.hibernate.transaction.JTATransactionFactory
|
|
@ -0,0 +1,7 @@
|
||||||
|
hibernate.connection.driver_class=org.h2.Driver
|
||||||
|
hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS MYDB1\\;CREATE SCHEMA IF NOT EXISTS MYDB2\\;
|
||||||
|
hibernate.connection.username=sa
|
||||||
|
hibernate.connection.autocommit=true
|
||||||
|
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
||||||
|
hibernate.multiTenancy=SCHEMA
|
||||||
|
hibernate.multi_tenant_connection_provider=com.baeldung.hibernate.multitenancy.schema.SchemaMultiTenantConnectionProvider
|
|
@ -0,0 +1,14 @@
|
||||||
|
hibernate.connection.driver_class=org.h2.Driver
|
||||||
|
hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1
|
||||||
|
hibernate.connection.username=sa
|
||||||
|
hibernate.connection.autocommit=true
|
||||||
|
jdbc.password=
|
||||||
|
|
||||||
|
hibernate.dialect=org.hibernate.spatial.dialect.h2geodb.GeoDBDialect
|
||||||
|
hibernate.show_sql=true
|
||||||
|
hibernate.hbm2ddl.auto=create-drop
|
||||||
|
|
||||||
|
hibernate.c3p0.min_size=5
|
||||||
|
hibernate.c3p0.max_size=20
|
||||||
|
hibernate.c3p0.acquire_increment=5
|
||||||
|
hibernate.c3p0.timeout=1800
|
|
@ -0,0 +1,14 @@
|
||||||
|
hibernate.connection.driver_class=org.h2.Driver
|
||||||
|
hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1
|
||||||
|
hibernate.connection.username=sa
|
||||||
|
hibernate.connection.autocommit=true
|
||||||
|
jdbc.password=
|
||||||
|
|
||||||
|
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
||||||
|
hibernate.show_sql=true
|
||||||
|
hibernate.hbm2ddl.auto=create-drop
|
||||||
|
|
||||||
|
hibernate.c3p0.min_size=5
|
||||||
|
hibernate.c3p0.max_size=20
|
||||||
|
hibernate.c3p0.acquire_increment=5
|
||||||
|
hibernate.c3p0.timeout=1800
|
|
@ -0,0 +1,25 @@
|
||||||
|
create sequence hibernate_sequence start with 1 increment by 1;
|
||||||
|
|
||||||
|
create table Football_Player (
|
||||||
|
id bigint not null,
|
||||||
|
name varchar(255),
|
||||||
|
primary key (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
insert into
|
||||||
|
Football_Player
|
||||||
|
(name, id)
|
||||||
|
values
|
||||||
|
('Cristiano Ronaldo', next value for hibernate_sequence);
|
||||||
|
|
||||||
|
insert into
|
||||||
|
Football_Player
|
||||||
|
(name, id)
|
||||||
|
values
|
||||||
|
('Lionel Messi', next value for hibernate_sequence);
|
||||||
|
|
||||||
|
insert into
|
||||||
|
Football_Player
|
||||||
|
(name, id)
|
||||||
|
values
|
||||||
|
('Gigi Buffon', next value for hibernate_sequence);
|
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Loading…
Reference in New Issue