diff --git a/persistence-modules/hibernate5-mapping/README.md b/persistence-modules/hibernate5-mapping/README.md
new file mode 100644
index 0000000000..f18b0b63de
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/README.md
@@ -0,0 +1,11 @@
+## Hibernate 5
+
+This module contains articles about Hibernate 5.
+
+### Relevant articles:
+
+- [Dynamic Mapping with Hibernate](http://www.baeldung.com/hibernate-dynamic-mapping)
+- [Hibernate Inheritance Mapping](http://www.baeldung.com/hibernate-inheritance)
+- [Mapping A Hibernate Query to a Custom Class](https://www.baeldung.com/hibernate-query-to-custom-class)
+- [Hibernate – Mapping Date and Time](http://www.baeldung.com/hibernate-date-time)
+- [Mapping LOB Data in Hibernate](http://www.baeldung.com/hibernate-lob)
\ No newline at end of file
diff --git a/persistence-modules/hibernate5-mapping/pom.xml b/persistence-modules/hibernate5-mapping/pom.xml
new file mode 100644
index 0000000000..59e0547671
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/pom.xml
@@ -0,0 +1,76 @@
+
+
+ 4.0.0
+ hibernate5-mapping
+ 0.0.1-SNAPSHOT
+ hibernate5-mapping
+
+
+ com.baeldung
+ persistence-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+ org.hibernate
+ hibernate-core
+ ${hibernate.version}
+
+
+ org.assertj
+ assertj-core
+ ${assertj-core.version}
+ test
+
+
+ com.h2database
+ h2
+ ${h2.version}
+
+
+ org.hibernate
+ hibernate-spatial
+ ${hibernate.version}
+
+
+ org.opengeo
+ geodb
+ ${geodb.version}
+
+
+ mysql
+ mysql-connector-java
+ ${mysql.version}
+
+
+ ch.vorburger.mariaDB4j
+ mariaDB4j
+ ${mariaDB4j.version}
+
+
+ org.hibernate
+ hibernate-testing
+ ${hibernate.version}
+
+
+
+
+
+ geodb-repo
+ GeoDB repository
+ http://repo.boundlessgeo.com/main/
+
+
+
+
+ 5.3.7.Final
+ 6.0.6
+ 2.2.3
+ 3.8.0
+ 0.9
+
+
+
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/HibernateUtil.java
new file mode 100644
index 0000000000..28e1af49ed
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/HibernateUtil.java
@@ -0,0 +1,96 @@
+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.entities.DeptEmployee;
+import com.baeldung.hibernate.pojo.Employee;
+import com.baeldung.hibernate.pojo.EntityDescription;
+import com.baeldung.hibernate.pojo.Phone;
+import com.baeldung.hibernate.pojo.TemporalValues;
+import com.baeldung.hibernate.pojo.inheritance.Animal;
+import com.baeldung.hibernate.pojo.inheritance.Bag;
+import com.baeldung.hibernate.pojo.inheritance.Book;
+import com.baeldung.hibernate.pojo.inheritance.Car;
+import com.baeldung.hibernate.pojo.inheritance.MyEmployee;
+import com.baeldung.hibernate.pojo.inheritance.MyProduct;
+import com.baeldung.hibernate.pojo.inheritance.Pen;
+import com.baeldung.hibernate.pojo.inheritance.Pet;
+import com.baeldung.hibernate.pojo.inheritance.Vehicle;
+
+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(Employee.class);
+ metadataSources.addAnnotatedClass(Phone.class);
+ metadataSources.addAnnotatedClass(EntityDescription.class);
+ metadataSources.addAnnotatedClass(TemporalValues.class);
+ metadataSources.addAnnotatedClass(DeptEmployee.class);
+ metadataSources.addAnnotatedClass(com.baeldung.hibernate.entities.Department.class);
+ metadataSources.addAnnotatedClass(Animal.class);
+ metadataSources.addAnnotatedClass(Bag.class);
+ metadataSources.addAnnotatedClass(Book.class);
+ metadataSources.addAnnotatedClass(Car.class);
+ metadataSources.addAnnotatedClass(MyEmployee.class);
+ metadataSources.addAnnotatedClass(MyProduct.class);
+ metadataSources.addAnnotatedClass(Pen.class);
+ metadataSources.addAnnotatedClass(Pet.class);
+ metadataSources.addAnnotatedClass(Vehicle.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;
+ }
+}
\ No newline at end of file
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/entities/Department.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/entities/Department.java
new file mode 100644
index 0000000000..ff94f4f849
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/entities/Department.java
@@ -0,0 +1,45 @@
+package com.baeldung.hibernate.entities;
+
+import java.util.List;
+
+import javax.persistence.*;
+
+@Entity
+public class Department {
+ @Id
+ @GeneratedValue(strategy = GenerationType.SEQUENCE)
+ private long id;
+
+ private String name;
+
+ @OneToMany(mappedBy="department")
+ private List employees;
+
+ public Department(String name) {
+ this.name = name;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List getEmployees() {
+ return employees;
+ }
+
+ public void setEmployees(List employees) {
+ this.employees = employees;
+ }
+}
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java
new file mode 100644
index 0000000000..6510e70650
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java
@@ -0,0 +1,83 @@
+package com.baeldung.hibernate.entities;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+
+@org.hibernate.annotations.NamedQueries({ @org.hibernate.annotations.NamedQuery(name = "DeptEmployee_FindByEmployeeNumber", query = "from DeptEmployee where employeeNumber = :employeeNo"),
+ @org.hibernate.annotations.NamedQuery(name = "DeptEmployee_FindAllByDesgination", query = "from DeptEmployee where designation = :designation"),
+ @org.hibernate.annotations.NamedQuery(name = "DeptEmployee_UpdateEmployeeDepartment", query = "Update DeptEmployee set department = :newDepartment where employeeNumber = :employeeNo"),
+ @org.hibernate.annotations.NamedQuery(name = "DeptEmployee_FindAllByDepartment", query = "from DeptEmployee where department = :department", timeout = 1, fetchSize = 10) })
+@org.hibernate.annotations.NamedNativeQueries({ @org.hibernate.annotations.NamedNativeQuery(name = "DeptEmployee_FindByEmployeeName", query = "select * from deptemployee emp where name=:name", resultClass = DeptEmployee.class),
+ @org.hibernate.annotations.NamedNativeQuery(name = "DeptEmployee_UpdateEmployeeDesignation", query = "call UPDATE_EMPLOYEE_DESIGNATION(:employeeNumber, :newDesignation)", resultClass = DeptEmployee.class) })
+@Entity
+public class DeptEmployee {
+ @Id
+ @GeneratedValue(strategy = GenerationType.SEQUENCE)
+ private long id;
+
+ private String employeeNumber;
+
+ private String title;
+
+ private String name;
+
+ @ManyToOne
+ private Department department;
+
+ public DeptEmployee(String name, String employeeNumber, Department department) {
+ this.name = name;
+ this.employeeNumber = employeeNumber;
+ this.department = department;
+ }
+
+ public DeptEmployee(String name, String employeeNumber, String title, Department department) {
+ super();
+ this.name = name;
+ this.employeeNumber = employeeNumber;
+ this.title = title;
+ this.department = department;
+ }
+
+ 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 Department getDepartment() {
+ return department;
+ }
+
+ public void setDepartment(Department department) {
+ this.department = department;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+}
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/lob/HibernateSessionUtil.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/lob/HibernateSessionUtil.java
new file mode 100644
index 0000000000..dc5242ee7c
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/lob/HibernateSessionUtil.java
@@ -0,0 +1,61 @@
+package com.baeldung.hibernate.lob;
+
+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.lob.model.User;
+
+public class HibernateSessionUtil {
+
+ 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(User.class);
+
+ Metadata metadata = metadataSources.buildMetadata();
+ 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.properties"));
+ try (FileInputStream inputStream = new FileInputStream(propertiesURL.getFile())) {
+ properties.load(inputStream);
+ }
+ return properties;
+ }
+}
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/lob/model/User.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/lob/model/User.java
new file mode 100644
index 0000000000..21f725b388
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/lob/model/User.java
@@ -0,0 +1,46 @@
+package com.baeldung.hibernate.lob.model;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="user")
+public class User {
+
+ @Id
+ private String id;
+
+ @Column(name = "name", columnDefinition="VARCHAR(128)")
+ private String name;
+
+ @Lob
+ @Column(name = "photo", columnDefinition="BLOB")
+ private byte[] photo;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public byte[] getPhoto() {
+ return photo;
+ }
+
+ public void setPhoto(byte[] photo) {
+ this.photo = photo;
+ }
+}
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/Employee.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/Employee.java
new file mode 100644
index 0000000000..e9732b2b67
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/Employee.java
@@ -0,0 +1,87 @@
+package com.baeldung.hibernate.pojo;
+
+import org.hibernate.annotations.*;
+
+import javax.persistence.Entity;
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Set;
+
+@Entity
+@Where(clause = "deleted = false")
+@FilterDef(name = "incomeLevelFilter", parameters = @ParamDef(name = "incomeLimit", type = "int"))
+@Filter(name = "incomeLevelFilter", condition = "grossIncome > :incomeLimit")
+public class Employee implements Serializable {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Integer id;
+
+ private long grossIncome;
+
+ private int taxInPercents;
+
+ private boolean deleted;
+
+ public long getTaxJavaWay() {
+ return grossIncome * taxInPercents / 100;
+ }
+
+ @Formula("grossIncome * taxInPercents / 100")
+ private long tax;
+
+ @OneToMany
+ @JoinColumn(name = "employee_id")
+ @Where(clause = "deleted = false")
+ private Set phones = new HashSet<>(0);
+
+ public Employee() {
+ }
+
+ public Employee(long grossIncome, int taxInPercents) {
+ this.grossIncome = grossIncome;
+ this.taxInPercents = taxInPercents;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public long getGrossIncome() {
+ return grossIncome;
+ }
+
+ public int getTaxInPercents() {
+ return taxInPercents;
+ }
+
+ public long getTax() {
+ return tax;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public void setGrossIncome(long grossIncome) {
+ this.grossIncome = grossIncome;
+ }
+
+ public void setTaxInPercents(int taxInPercents) {
+ this.taxInPercents = taxInPercents;
+ }
+
+ public boolean getDeleted() {
+ return deleted;
+ }
+
+ public void setDeleted(boolean deleted) {
+ this.deleted = deleted;
+ }
+
+ public Set getPhones() {
+ return phones;
+ }
+
+}
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/EntityDescription.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/EntityDescription.java
new file mode 100644
index 0000000000..131bb73a80
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/EntityDescription.java
@@ -0,0 +1,55 @@
+package com.baeldung.hibernate.pojo;
+
+import org.hibernate.annotations.Any;
+
+import javax.persistence.*;
+import java.io.Serializable;
+
+@Entity
+public class EntityDescription implements Serializable {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Integer id;
+
+ private String description;
+
+ @Any(
+ metaDef = "EntityDescriptionMetaDef",
+ metaColumn = @Column(name = "entity_type")
+ )
+ @JoinColumn(name = "entity_id")
+ private Serializable entity;
+
+ public EntityDescription() {
+ }
+
+ public EntityDescription(String description, Serializable entity) {
+ this.description = description;
+ this.entity = entity;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Serializable getEntity() {
+ return entity;
+ }
+
+ public void setEntity(Serializable entity) {
+ this.entity = entity;
+ }
+}
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/Phone.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/Phone.java
new file mode 100644
index 0000000000..d923bda5de
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/Phone.java
@@ -0,0 +1,50 @@
+package com.baeldung.hibernate.pojo;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import java.io.Serializable;
+
+@Entity
+public class Phone implements Serializable {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Integer id;
+
+ private boolean deleted;
+
+ private String number;
+
+ public Phone() {
+ }
+
+ public Phone(String number) {
+ this.number = number;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public boolean isDeleted() {
+ return deleted;
+ }
+
+ public void setDeleted(boolean deleted) {
+ this.deleted = deleted;
+ }
+
+ public String getNumber() {
+ return number;
+ }
+
+ public void setNumber(String number) {
+ this.number = number;
+ }
+}
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/Result.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/Result.java
new file mode 100644
index 0000000000..607269a267
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/Result.java
@@ -0,0 +1,31 @@
+package com.baeldung.hibernate.pojo;
+
+public class Result {
+ private String employeeName;
+
+ private String departmentName;
+
+ public Result(String employeeName, String departmentName) {
+ this.employeeName = employeeName;
+ this.departmentName = departmentName;
+ }
+
+ public Result() {
+ }
+
+ public String getEmployeeName() {
+ return employeeName;
+ }
+
+ public void setEmployeeName(String employeeName) {
+ this.employeeName = employeeName;
+ }
+
+ public String getDepartmentName() {
+ return departmentName;
+ }
+
+ public void setDepartmentName(String departmentName) {
+ this.departmentName = departmentName;
+ }
+}
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/TemporalValues.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/TemporalValues.java
new file mode 100644
index 0000000000..f3fe095cae
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/TemporalValues.java
@@ -0,0 +1,195 @@
+package com.baeldung.hibernate.pojo;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.sql.Date;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.time.*;
+import java.util.Calendar;
+
+@Entity
+public class TemporalValues implements Serializable {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ @Basic
+ private java.sql.Date sqlDate;
+
+ @Basic
+ private java.sql.Time sqlTime;
+
+ @Basic
+ private java.sql.Timestamp sqlTimestamp;
+
+ @Basic
+ @Temporal(TemporalType.DATE)
+ private java.util.Date utilDate;
+
+ @Basic
+ @Temporal(TemporalType.TIME)
+ private java.util.Date utilTime;
+
+ @Basic
+ @Temporal(TemporalType.TIMESTAMP)
+ private java.util.Date utilTimestamp;
+
+ @Basic
+ @Temporal(TemporalType.DATE)
+ private java.util.Calendar calendarDate;
+
+ @Basic
+ @Temporal(TemporalType.TIMESTAMP)
+ private java.util.Calendar calendarTimestamp;
+
+ @Basic
+ private java.time.LocalDate localDate;
+
+ @Basic
+ private java.time.LocalTime localTime;
+
+ @Basic
+ private java.time.OffsetTime offsetTime;
+
+ @Basic
+ private java.time.Instant instant;
+
+ @Basic
+ private java.time.LocalDateTime localDateTime;
+
+ @Basic
+ private java.time.OffsetDateTime offsetDateTime;
+
+ @Basic
+ private java.time.ZonedDateTime zonedDateTime;
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public Date getSqlDate() {
+ return sqlDate;
+ }
+
+ public void setSqlDate(Date sqlDate) {
+ this.sqlDate = sqlDate;
+ }
+
+ public Time getSqlTime() {
+ return sqlTime;
+ }
+
+ public void setSqlTime(Time sqlTime) {
+ this.sqlTime = sqlTime;
+ }
+
+ public Timestamp getSqlTimestamp() {
+ return sqlTimestamp;
+ }
+
+ public void setSqlTimestamp(Timestamp sqlTimestamp) {
+ this.sqlTimestamp = sqlTimestamp;
+ }
+
+ public java.util.Date getUtilDate() {
+ return utilDate;
+ }
+
+ public void setUtilDate(java.util.Date utilDate) {
+ this.utilDate = utilDate;
+ }
+
+ public java.util.Date getUtilTime() {
+ return utilTime;
+ }
+
+ public void setUtilTime(java.util.Date utilTime) {
+ this.utilTime = utilTime;
+ }
+
+ public java.util.Date getUtilTimestamp() {
+ return utilTimestamp;
+ }
+
+ public void setUtilTimestamp(java.util.Date utilTimestamp) {
+ this.utilTimestamp = utilTimestamp;
+ }
+
+ public Calendar getCalendarDate() {
+ return calendarDate;
+ }
+
+ public void setCalendarDate(Calendar calendarDate) {
+ this.calendarDate = calendarDate;
+ }
+
+ public Calendar getCalendarTimestamp() {
+ return calendarTimestamp;
+ }
+
+ public void setCalendarTimestamp(Calendar calendarTimestamp) {
+ this.calendarTimestamp = calendarTimestamp;
+ }
+
+ public LocalDate getLocalDate() {
+ return localDate;
+ }
+
+ public void setLocalDate(LocalDate localDate) {
+ this.localDate = localDate;
+ }
+
+ public LocalTime getLocalTime() {
+ return localTime;
+ }
+
+ public void setLocalTime(LocalTime localTime) {
+ this.localTime = localTime;
+ }
+
+ public OffsetTime getOffsetTime() {
+ return offsetTime;
+ }
+
+ public void setOffsetTime(OffsetTime offsetTime) {
+ this.offsetTime = offsetTime;
+ }
+
+ public Instant getInstant() {
+ return instant;
+ }
+
+ public void setInstant(Instant instant) {
+ this.instant = instant;
+ }
+
+ public LocalDateTime getLocalDateTime() {
+ return localDateTime;
+ }
+
+ public void setLocalDateTime(LocalDateTime localDateTime) {
+ this.localDateTime = localDateTime;
+ }
+
+ public OffsetDateTime getOffsetDateTime() {
+ return offsetDateTime;
+ }
+
+ public void setOffsetDateTime(OffsetDateTime offsetDateTime) {
+ this.offsetDateTime = offsetDateTime;
+ }
+
+ public ZonedDateTime getZonedDateTime() {
+ return zonedDateTime;
+ }
+
+ public void setZonedDateTime(ZonedDateTime zonedDateTime) {
+ this.zonedDateTime = zonedDateTime;
+ }
+}
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/generator/MyGenerator.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/generator/MyGenerator.java
new file mode 100644
index 0000000000..17ffe9b7e1
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/generator/MyGenerator.java
@@ -0,0 +1,41 @@
+package com.baeldung.hibernate.pojo.generator;
+
+import java.io.Serializable;
+import java.util.Properties;
+import java.util.stream.Stream;
+
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.engine.spi.SharedSessionContractImplementor;
+import org.hibernate.id.Configurable;
+import org.hibernate.id.IdentifierGenerator;
+import org.hibernate.service.ServiceRegistry;
+import org.hibernate.type.Type;
+
+public class MyGenerator implements IdentifierGenerator, Configurable {
+
+ private String prefix;
+
+ @Override
+ public Serializable generate(SharedSessionContractImplementor session, Object obj) throws HibernateException {
+
+ String query = String.format("select %s from %s",
+ session.getEntityPersister(obj.getClass().getName(), obj).getIdentifierPropertyName(),
+ obj.getClass().getSimpleName());
+
+ Stream ids = session.createQuery(query).stream();
+
+ Long max = ids.map(o -> o.replace(prefix + "-", ""))
+ .mapToLong(Long::parseLong)
+ .max()
+ .orElse(0L);
+
+ return prefix + "-" + (max + 1);
+ }
+
+ @Override
+ public void configure(Type type, Properties properties, ServiceRegistry serviceRegistry) throws MappingException {
+ prefix = properties.getProperty("prefix");
+ }
+
+}
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Animal.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Animal.java
new file mode 100644
index 0000000000..6fe7f915fc
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Animal.java
@@ -0,0 +1,40 @@
+package com.baeldung.hibernate.pojo.inheritance;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+
+@Entity
+@Inheritance(strategy = InheritanceType.JOINED)
+public class Animal {
+
+ @Id
+ private long animalId;
+
+ private String species;
+
+ public Animal() {}
+
+ public Animal(long animalId, String species) {
+ this.animalId = animalId;
+ this.species = species;
+ }
+
+ public long getAnimalId() {
+ return animalId;
+ }
+
+ public void setAnimalId(long animalId) {
+ this.animalId = animalId;
+ }
+
+ public String getSpecies() {
+ return species;
+ }
+
+ public void setSpecies(String species) {
+ this.species = species;
+ }
+
+}
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Bag.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Bag.java
new file mode 100644
index 0000000000..fa6e1b4bef
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Bag.java
@@ -0,0 +1,38 @@
+package com.baeldung.hibernate.pojo.inheritance;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+import org.hibernate.annotations.Polymorphism;
+import org.hibernate.annotations.PolymorphismType;
+
+@Entity
+@Polymorphism(type = PolymorphismType.EXPLICIT)
+public class Bag implements Item {
+
+ @Id
+ private long bagId;
+
+ private String type;
+
+ public Bag(long bagId, String type) {
+ this.bagId = bagId;
+ this.type = type;
+ }
+
+ public long getBagId() {
+ return bagId;
+ }
+
+ public void setBagId(long bagId) {
+ this.bagId = bagId;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+}
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Book.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Book.java
new file mode 100644
index 0000000000..36ca8dd77c
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Book.java
@@ -0,0 +1,27 @@
+package com.baeldung.hibernate.pojo.inheritance;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+@Entity
+@DiscriminatorValue("1")
+public class Book extends MyProduct {
+ private String author;
+
+ public Book() {
+ }
+
+ public Book(long productId, String name, String author) {
+ super(productId, name);
+ this.author = author;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+
+}
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Car.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Car.java
new file mode 100644
index 0000000000..49d1f7749a
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Car.java
@@ -0,0 +1,25 @@
+package com.baeldung.hibernate.pojo.inheritance;
+
+import javax.persistence.Entity;
+
+@Entity
+public class Car extends Vehicle {
+ private String engine;
+
+ public Car() {
+ }
+
+ public Car(long vehicleId, String manufacturer, String engine) {
+ super(vehicleId, manufacturer);
+ this.engine = engine;
+ }
+
+ public String getEngine() {
+ return engine;
+ }
+
+ public void setEngine(String engine) {
+ this.engine = engine;
+ }
+
+}
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Item.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Item.java
new file mode 100644
index 0000000000..9656030736
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Item.java
@@ -0,0 +1,5 @@
+package com.baeldung.hibernate.pojo.inheritance;
+
+public interface Item {
+
+}
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyEmployee.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyEmployee.java
new file mode 100644
index 0000000000..9a6bce16cf
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyEmployee.java
@@ -0,0 +1,22 @@
+package com.baeldung.hibernate.pojo.inheritance;
+
+import javax.persistence.Entity;
+
+@Entity
+public class MyEmployee extends Person {
+ private String company;
+
+ public MyEmployee(long personId, String name, String company) {
+ super(personId, name);
+ this.company = company;
+ }
+
+ public String getCompany() {
+ return company;
+ }
+
+ public void setCompany(String company) {
+ this.company = company;
+ }
+
+}
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyProduct.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyProduct.java
new file mode 100644
index 0000000000..13f04d8904
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyProduct.java
@@ -0,0 +1,47 @@
+package com.baeldung.hibernate.pojo.inheritance;
+
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.DiscriminatorType;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+
+import org.hibernate.annotations.DiscriminatorFormula;
+
+@Entity
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name = "product_type", discriminatorType = DiscriminatorType.INTEGER)
+// @DiscriminatorFormula("case when author is not null then 1 else 2 end")
+public class MyProduct {
+ @Id
+ private long productId;
+
+ private String name;
+
+ public MyProduct() {
+ }
+
+ public MyProduct(long productId, String name) {
+ super();
+ this.productId = productId;
+ this.name = name;
+ }
+
+ public long getProductId() {
+ return productId;
+ }
+
+ public void setProductId(long productId) {
+ this.productId = productId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+}
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pen.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pen.java
new file mode 100644
index 0000000000..32b77e52af
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pen.java
@@ -0,0 +1,27 @@
+package com.baeldung.hibernate.pojo.inheritance;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+@Entity
+@DiscriminatorValue("2")
+public class Pen extends MyProduct {
+ private String color;
+
+ public Pen() {
+ }
+
+ public Pen(long productId, String name, String color) {
+ super(productId, name);
+ this.color = color;
+ }
+
+ public String getColor() {
+ return color;
+ }
+
+ public void setColor(String color) {
+ this.color = color;
+ }
+
+}
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Person.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Person.java
new file mode 100644
index 0000000000..99084b88af
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Person.java
@@ -0,0 +1,38 @@
+package com.baeldung.hibernate.pojo.inheritance;
+
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+
+@MappedSuperclass
+public class Person {
+
+ @Id
+ private long personId;
+
+ private String name;
+
+ public Person() {
+ }
+
+ public Person(long personId, String name) {
+ this.personId = personId;
+ this.name = name;
+ }
+
+ public long getPersonId() {
+ return personId;
+ }
+
+ public void setPersonId(long personId) {
+ this.personId = personId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+}
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pet.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pet.java
new file mode 100644
index 0000000000..870b3cd684
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pet.java
@@ -0,0 +1,27 @@
+package com.baeldung.hibernate.pojo.inheritance;
+
+import javax.persistence.Entity;
+import javax.persistence.PrimaryKeyJoinColumn;
+
+@Entity
+@PrimaryKeyJoinColumn(name = "petId")
+public class Pet extends Animal {
+ private String name;
+
+ public Pet() {
+ }
+
+ public Pet(long animalId, String species, String name) {
+ super(animalId, species);
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+}
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Vehicle.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Vehicle.java
new file mode 100644
index 0000000000..b2a920573e
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/inheritance/Vehicle.java
@@ -0,0 +1,40 @@
+package com.baeldung.hibernate.pojo.inheritance;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+
+@Entity
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+public class Vehicle {
+ @Id
+ private long vehicleId;
+
+ private String manufacturer;
+
+ public Vehicle() {
+ }
+
+ public Vehicle(long vehicleId, String manufacturer) {
+ this.vehicleId = vehicleId;
+ this.manufacturer = manufacturer;
+ }
+
+ public long getVehicleId() {
+ return vehicleId;
+ }
+
+ public void setVehicleId(long vehicleId) {
+ this.vehicleId = vehicleId;
+ }
+
+ public String getManufacturer() {
+ return manufacturer;
+ }
+
+ public void setManufacturer(String manufacturer) {
+ this.manufacturer = manufacturer;
+ }
+
+}
diff --git a/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/package-info.java b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/package-info.java
new file mode 100644
index 0000000000..992cda7c1d
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/java/com/baeldung/hibernate/pojo/package-info.java
@@ -0,0 +1,9 @@
+@AnyMetaDef(name = "EntityDescriptionMetaDef", metaType = "string", idType = "int",
+ metaValues = {
+ @MetaValue(value = "Employee", targetEntity = Employee.class),
+ @MetaValue(value = "Phone", targetEntity = Phone.class)
+ })
+package com.baeldung.hibernate.pojo;
+
+import org.hibernate.annotations.AnyMetaDef;
+import org.hibernate.annotations.MetaValue;
\ No newline at end of file
diff --git a/persistence-modules/hibernate5-mapping/src/main/resources/META-INF/persistence.xml b/persistence-modules/hibernate5-mapping/src/main/resources/META-INF/persistence.xml
new file mode 100644
index 0000000000..474eeb7a44
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/resources/META-INF/persistence.xml
@@ -0,0 +1,18 @@
+
+
+
+ Hibernate EntityManager Demo
+ true
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/persistence-modules/hibernate5-mapping/src/main/resources/logback.xml b/persistence-modules/hibernate5-mapping/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/persistence-modules/hibernate5-mapping/src/test/java/com/baeldung/hibernate/CustomClassIntegrationTest.java b/persistence-modules/hibernate5-mapping/src/test/java/com/baeldung/hibernate/CustomClassIntegrationTest.java
new file mode 100644
index 0000000000..699890c457
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/test/java/com/baeldung/hibernate/CustomClassIntegrationTest.java
@@ -0,0 +1,78 @@
+package com.baeldung.hibernate;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.IOException;
+import java.util.List;
+
+import com.baeldung.hibernate.entities.DeptEmployee;
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.query.Query;
+import org.hibernate.transform.Transformers;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import com.baeldung.hibernate.entities.Department;
+import com.baeldung.hibernate.pojo.Result;
+
+public class CustomClassIntegrationTest {
+
+ private Session session;
+
+ private Transaction transaction;
+
+ @BeforeEach
+ public void setUp() throws IOException {
+ session = HibernateUtil.getSessionFactory().openSession();
+ transaction = session.beginTransaction();
+ session.createNativeQuery("delete from department").executeUpdate();
+ Department department = new Department("Sales");
+ DeptEmployee employee = new DeptEmployee("John Smith", "001", department);
+ session.persist(department);
+ session.persist(employee);
+ transaction.commit();
+ transaction = session.beginTransaction();
+ }
+
+ @Test
+ public void whenAllManagersAreSelected_ThenObjectGraphIsReturned() {
+ Query query = session.createQuery("from com.baeldung.hibernate.entities.DeptEmployee");
+ List deptEmployees = query.list();
+ DeptEmployee deptEmployee = deptEmployees.get(0);
+ assertEquals("John Smith", deptEmployee.getName());
+ assertEquals("Sales", deptEmployee.getDepartment().getName());
+ }
+
+ @Test
+ public void whenIndividualPropertiesAreSelected_ThenObjectArrayIsReturned() {
+ Query query = session.createQuery("select m.name, m.department.name from com.baeldung.hibernate.entities.DeptEmployee m");
+ List managers = query.list();
+ Object[] manager = (Object[]) managers.get(0);
+ assertEquals("John Smith", manager[0]);
+ assertEquals("Sales", manager[1]);
+ }
+
+ @Test
+ public void whenResultConstructorInSelect_ThenListOfResultIsReturned() {
+ Query query = session.createQuery("select new com.baeldung.hibernate.pojo.Result(m.name, m.department.name) "
+ + "from DeptEmployee m");
+ List results = query.list();
+ Result result = results.get(0);
+ assertEquals("John Smith", result.getEmployeeName());
+ assertEquals("Sales", result.getDepartmentName());
+ }
+
+ @Test
+ public void whenResultTransformerOnQuery_ThenListOfResultIsReturned() {
+ Query query = session.createQuery("select m.name as employeeName, m.department.name as departmentName "
+ + "from com.baeldung.hibernate.entities.DeptEmployee m");
+ query.setResultTransformer(Transformers.aliasToBean(Result.class));
+ List results = query.list();
+ Result result = results.get(0);
+ assertEquals("John Smith", result.getEmployeeName());
+ assertEquals("Sales", result.getDepartmentName());
+ }
+
+
+}
diff --git a/persistence-modules/hibernate5-mapping/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java b/persistence-modules/hibernate5-mapping/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java
new file mode 100644
index 0000000000..7a112200b5
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java
@@ -0,0 +1,160 @@
+package com.baeldung.hibernate;
+
+import com.baeldung.hibernate.pojo.Employee;
+import com.baeldung.hibernate.pojo.EntityDescription;
+import com.baeldung.hibernate.pojo.Phone;
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class DynamicMappingIntegrationTest {
+
+ private Session session;
+
+ private Transaction transaction;
+
+ @Before
+ public void setUp() throws IOException {
+ session = HibernateUtil.getSessionFactory().openSession();
+ transaction = session.beginTransaction();
+
+ session.createNativeQuery("delete from phone").executeUpdate();
+ session.createNativeQuery("delete from employee").executeUpdate();
+
+ transaction.commit();
+ transaction = session.beginTransaction();
+ }
+
+ @After
+ public void tearDown() {
+ transaction.rollback();
+ session.close();
+ }
+
+ @Test
+ public void givenEntity_whenFieldMappedWithFormula_thenFieldIsCalculated() {
+ Employee employee = new Employee(10_000L, 25);
+ assertThat(employee.getTaxJavaWay()).isEqualTo(2_500L);
+
+ session.save(employee);
+ session.flush();
+ session.clear();
+
+ employee = session.get(Employee.class, employee.getId());
+ assertThat(employee.getTax()).isEqualTo(2_500L);
+ }
+
+ @Test
+ public void givenEntityMappedWithWhere_whenDeletedIsTrue_thenEntityNotFetched() {
+ Employee employee = new Employee();
+
+ session.save(employee);
+ session.clear();
+
+ employee = session.find(Employee.class, employee.getId());
+ assertThat(employee).isNotNull();
+
+ employee.setDeleted(true);
+ session.flush();
+
+ employee = session.find(Employee.class, employee.getId());
+ assertThat(employee).isNotNull();
+
+ session.clear();
+
+ employee = session.find(Employee.class, employee.getId());
+ assertThat(employee).isNull();
+
+ }
+
+ @Test
+ public void givenCollectionMappedWithWhere_whenDeletedIsTrue_thenEntityNotFetched() {
+ Employee employee = new Employee();
+ Phone phone1 = new Phone("555-45-67");
+ Phone phone2 = new Phone("555-89-01");
+ employee.getPhones().add(phone1);
+ employee.getPhones().add(phone2);
+
+ session.save(phone1);
+ session.save(phone2);
+ session.save(employee);
+ session.flush();
+ session.clear();
+
+ employee = session.find(Employee.class, employee.getId());
+ assertThat(employee.getPhones()).hasSize(2);
+
+ employee.getPhones().iterator().next().setDeleted(true);
+ session.flush();
+ session.clear();
+
+ employee = session.find(Employee.class, employee.getId());
+ assertThat(employee.getPhones()).hasSize(1);
+
+ List fullPhoneList = session.createQuery("from Phone").getResultList();
+ assertThat(fullPhoneList).hasSize(2);
+
+ }
+
+ @Test
+ public void givenFilterByIncome_whenIncomeLimitSet_thenFilterIsApplied() throws IOException {
+ session.save(new Employee(10_000, 25));
+ session.save(new Employee(12_000, 25));
+ session.save(new Employee(15_000, 25));
+
+ session.flush();
+ session.clear();
+
+ session.enableFilter("incomeLevelFilter")
+ .setParameter("incomeLimit", 11_000);
+
+ List employees = session.createQuery("from Employee").getResultList();
+
+ assertThat(employees).hasSize(2);
+
+ Employee employee = session.get(Employee.class, 1);
+ assertThat(employee.getGrossIncome()).isEqualTo(10_000);
+
+ session.disableFilter("incomeLevelFilter");
+ employees = session.createQuery("from Employee").getResultList();
+
+ assertThat(employees).hasSize(3);
+
+ }
+
+ @Test
+ public void givenMappingWithAny_whenDescriptionAddedToEntity_thenDescriptionCanReferAnyEntity() {
+ Employee employee = new Employee();
+ Phone phone1 = new Phone("555-45-67");
+ Phone phone2 = new Phone("555-89-01");
+ employee.getPhones().add(phone1);
+ employee.getPhones().add(phone2);
+
+ EntityDescription employeeDescription = new EntityDescription("Send to conference next year", employee);
+ EntityDescription phone1Description = new EntityDescription("Home phone (do not call after 10PM)", phone1);
+ EntityDescription phone2Description = new EntityDescription("Work phone", phone1);
+
+ session.save(phone1);
+ session.save(phone2);
+ session.save(employee);
+ session.save(employeeDescription);
+ session.save(phone1Description);
+ session.save(phone2Description);
+ session.flush();
+ session.clear();
+
+ List descriptions = session.createQuery("from EntityDescription").getResultList();
+
+ assertThat(Employee.class.isAssignableFrom(descriptions.get(0).getEntity().getClass())).isTrue();
+ assertThat(Phone.class.isAssignableFrom(descriptions.get(1).getEntity().getClass())).isTrue();
+ assertThat(Phone.class.isAssignableFrom(descriptions.get(2).getEntity().getClass())).isTrue();
+ }
+
+}
diff --git a/persistence-modules/hibernate5-mapping/src/test/java/com/baeldung/hibernate/InheritanceMappingIntegrationTest.java b/persistence-modules/hibernate5-mapping/src/test/java/com/baeldung/hibernate/InheritanceMappingIntegrationTest.java
new file mode 100644
index 0000000000..0f35dbb8af
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/test/java/com/baeldung/hibernate/InheritanceMappingIntegrationTest.java
@@ -0,0 +1,89 @@
+package com.baeldung.hibernate;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.IOException;
+
+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.inheritance.Bag;
+import com.baeldung.hibernate.pojo.inheritance.Book;
+import com.baeldung.hibernate.pojo.inheritance.Car;
+import com.baeldung.hibernate.pojo.inheritance.MyEmployee;
+import com.baeldung.hibernate.pojo.inheritance.Pen;
+import com.baeldung.hibernate.pojo.inheritance.Pet;
+
+public class InheritanceMappingIntegrationTest {
+ private Session session;
+
+ private Transaction transaction;
+
+ @Before
+ public void setUp() throws IOException {
+ session = HibernateUtil.getSessionFactory()
+ .openSession();
+ transaction = session.beginTransaction();
+ }
+
+ @After
+ public void tearDown() {
+ transaction.rollback();
+ session.close();
+ }
+
+ @Test
+ public void givenSubclasses_whenQuerySingleTableSuperclass_thenOk() {
+ Book book = new Book(1, "1984", "George Orwell");
+ session.save(book);
+ Pen pen = new Pen(2, "my pen", "blue");
+ session.save(pen);
+
+ assertThat(session.createQuery("from MyProduct")
+ .getResultList()
+ .size()).isEqualTo(2);
+ }
+
+ @Test
+ public void givenSubclasses_whenQueryMappedSuperclass_thenOk() {
+ MyEmployee emp = new MyEmployee(1, "john", "baeldung");
+ session.save(emp);
+
+ assertThat(session.createQuery("from com.baeldung.hibernate.pojo.inheritance.Person")
+ .getResultList()
+ .size()).isEqualTo(1);
+ }
+
+ @Test
+ public void givenSubclasses_whenQueryJoinedTableSuperclass_thenOk() {
+ Pet pet = new Pet(1, "dog", "lassie");
+ session.save(pet);
+
+ assertThat(session.createQuery("from Animal")
+ .getResultList()
+ .size()).isEqualTo(1);
+ }
+
+ @Test
+ public void givenSubclasses_whenQueryTablePerClassSuperclass_thenOk() {
+ Car car = new Car(1, "audi", "xyz");
+ session.save(car);
+
+ assertThat(session.createQuery("from Vehicle")
+ .getResultList()
+ .size()).isEqualTo(1);
+ }
+
+ @Test
+ public void givenSubclasses_whenQueryNonMappedInterface_thenOk() {
+ Bag bag = new Bag(1, "large");
+ session.save(bag);
+
+ assertThat(session.createQuery("from com.baeldung.hibernate.pojo.inheritance.Item")
+ .getResultList()
+ .size()).isEqualTo(0);
+ }
+}
diff --git a/persistence-modules/hibernate5-mapping/src/test/java/com/baeldung/hibernate/TemporalValuesUnitTest.java b/persistence-modules/hibernate5-mapping/src/test/java/com/baeldung/hibernate/TemporalValuesUnitTest.java
new file mode 100644
index 0000000000..91c41af0fe
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/test/java/com/baeldung/hibernate/TemporalValuesUnitTest.java
@@ -0,0 +1,128 @@
+package com.baeldung.hibernate;
+
+import com.baeldung.hibernate.pojo.TemporalValues;
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.time.*;
+import java.util.Calendar;
+import java.util.TimeZone;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class TemporalValuesUnitTest {
+
+ private Session session;
+
+ private Transaction transaction;
+
+ @Before
+ public void setUp() throws IOException {
+ session = HibernateUtil.getSessionFactory().withOptions()
+ .jdbcTimeZone(TimeZone.getTimeZone("UTC"))
+ .openSession();
+ transaction = session.beginTransaction();
+ session.createNativeQuery("delete from temporalvalues").executeUpdate();
+ }
+
+ @After
+ public void tearDown() {
+ transaction.rollback();
+ session.close();
+ }
+
+ @Test
+ public void givenEntity_whenMappingSqlTypes_thenTemporalIsSelectedAutomatically() {
+ TemporalValues temporalValues = new TemporalValues();
+ temporalValues.setSqlDate(java.sql.Date.valueOf("2017-11-15"));
+ temporalValues.setSqlTime(java.sql.Time.valueOf("15:30:14"));
+ temporalValues.setSqlTimestamp(java.sql.Timestamp.valueOf("2017-11-15 15:30:14.332"));
+
+ session.save(temporalValues);
+ session.flush();
+ session.clear();
+
+ temporalValues = session.get(TemporalValues.class, temporalValues.getId());
+ assertThat(temporalValues.getSqlDate()).isEqualTo(java.sql.Date.valueOf("2017-11-15"));
+ assertThat(temporalValues.getSqlTime()).isEqualTo(java.sql.Time.valueOf("15:30:14"));
+ assertThat(temporalValues.getSqlTimestamp()).isEqualTo(java.sql.Timestamp.valueOf("2017-11-15 15:30:14.332"));
+
+ }
+
+ @Test
+ public void givenEntity_whenMappingUtilDateType_thenTemporalIsSpecifiedExplicitly() throws Exception {
+ TemporalValues temporalValues = new TemporalValues();
+ temporalValues.setUtilDate(new SimpleDateFormat("yyyy-MM-dd").parse("2017-11-15"));
+ temporalValues.setUtilTime(new SimpleDateFormat("HH:mm:ss").parse("15:30:14"));
+ temporalValues.setUtilTimestamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse("2017-11-15 15:30:14.332"));
+
+ session.save(temporalValues);
+ session.flush();
+ session.clear();
+
+ temporalValues = session.get(TemporalValues.class, temporalValues.getId());
+ assertThat(temporalValues.getUtilDate()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2017-11-15"));
+ assertThat(temporalValues.getUtilTime()).isEqualTo(new SimpleDateFormat("HH:mm:ss").parse("15:30:14"));
+ assertThat(temporalValues.getUtilTimestamp()).isEqualTo(java.sql.Timestamp.valueOf("2017-11-15 15:30:14.332"));
+
+ }
+
+ @Test
+ public void givenEntity_whenMappingCalendarType_thenTemporalIsSpecifiedExplicitly() throws Exception {
+ TemporalValues temporalValues = new TemporalValues();
+
+ Calendar calendarDate = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+ calendarDate.set(Calendar.YEAR, 2017);
+ calendarDate.set(Calendar.MONTH, 10);
+ calendarDate.set(Calendar.DAY_OF_MONTH, 15);
+ temporalValues.setCalendarDate(calendarDate);
+
+ Calendar calendarTimestamp = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+ calendarTimestamp.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse("2017-11-15 15:30:14.322"));
+ temporalValues.setCalendarTimestamp(calendarTimestamp);
+
+ session.save(temporalValues);
+ session.flush();
+ session.clear();
+
+ temporalValues = session.get(TemporalValues.class, temporalValues.getId());
+ assertThat(temporalValues.getCalendarDate().getTime()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2017-11-15"));
+ assertThat(temporalValues.getCalendarTimestamp().getTime()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse("2017-11-15 15:30:14.322"));
+
+ }
+
+ @Test
+ public void givenEntity_whenMappingJavaTimeTypes_thenTemporalIsSelectedAutomatically() {
+ TemporalValues temporalValues = new TemporalValues();
+
+ temporalValues.setLocalDate(LocalDate.parse("2017-11-15"));
+ temporalValues.setLocalTime(LocalTime.parse("15:30:18"));
+ temporalValues.setOffsetTime(OffsetTime.parse("08:22:12+01:00"));
+
+ System.out.println("********"+OffsetTime.parse("08:22:12+01:00").toString());
+ temporalValues.setInstant(Instant.parse("2017-11-15T08:22:12Z"));
+ temporalValues.setLocalDateTime(LocalDateTime.parse("2017-11-15T08:22:12"));
+ temporalValues.setOffsetDateTime(OffsetDateTime.parse("2017-11-15T08:22:12+01:00"));
+ temporalValues.setZonedDateTime(ZonedDateTime.parse("2017-11-15T08:22:12+01:00[Europe/Paris]"));
+
+ session.save(temporalValues);
+ session.flush();
+ session.clear();
+
+ temporalValues = session.get(TemporalValues.class, temporalValues.getId());
+ assertThat(temporalValues.getLocalDate()).isEqualTo(LocalDate.parse("2017-11-15"));
+ assertThat(temporalValues.getLocalTime()).isEqualTo(LocalTime.parse("15:30:18"));
+ //assertThat(temporalValues.getOffsetTime()).isEqualTo(OffsetTime.parse("08:22:12+01:00"));
+ assertThat(temporalValues.getInstant()).isEqualTo(Instant.parse("2017-11-15T08:22:12Z"));
+ assertThat(temporalValues.getLocalDateTime()).isEqualTo(LocalDateTime.parse("2017-11-15T08:22:12"));
+ //assertThat(temporalValues.getOffsetDateTime()).isEqualTo(OffsetDateTime.parse("2017-11-15T08:22:12+01:00"));
+ assertThat(temporalValues.getZonedDateTime()).isEqualTo(ZonedDateTime.parse("2017-11-15T08:22:12+01:00[Europe/Paris]"));
+
+ }
+
+}
diff --git a/persistence-modules/hibernate5-mapping/src/test/java/com/baeldung/hibernate/lob/LobUnitTest.java b/persistence-modules/hibernate5-mapping/src/test/java/com/baeldung/hibernate/lob/LobUnitTest.java
new file mode 100644
index 0000000000..398b2290fa
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/test/java/com/baeldung/hibernate/lob/LobUnitTest.java
@@ -0,0 +1,61 @@
+package com.baeldung.hibernate.lob;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+
+import org.apache.commons.io.IOUtils;
+import org.hibernate.HibernateException;
+import org.hibernate.Session;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.baeldung.hibernate.lob.model.User;
+
+public class LobUnitTest {
+
+ private Session session;
+
+ @Before
+ public void init(){
+ try {
+ session = HibernateSessionUtil.getSessionFactory("hibernate.properties")
+ .openSession();
+ } catch (HibernateException | IOException e) {
+ fail("Failed to initiate Hibernate Session [Exception:" + e.toString() + "]");
+ }
+ }
+
+ @After
+ public void close(){
+ if(session != null) session.close();
+ }
+
+ @Test
+ public void givenValidInsertLobObject_whenQueried_returnSameDataAsInserted(){
+ User user = new User();
+ try(InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("profile.png");) {
+ // Get Image file from the resource
+ if(inputStream == null) fail("Unable to get resources");
+ user.setId("1");
+ user.setName("User");
+ user.setPhoto(IOUtils.toByteArray(inputStream));
+
+ session.persist(user);
+ } catch (IOException e) {
+ fail("Unable to read input stream");
+ }
+
+ User result = session.find(User.class, "1");
+
+ assertNotNull("Query result is null", result);
+ assertEquals("User's name is invalid", user.getName(), result.getName() );
+ assertTrue("User's photo is corrupted", Arrays.equals(user.getPhoto(), result.getPhoto()) );
+ }
+}
diff --git a/persistence-modules/hibernate5-mapping/src/test/resources/hibernate.properties b/persistence-modules/hibernate5-mapping/src/test/resources/hibernate.properties
new file mode 100644
index 0000000000..c14782ce0f
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/test/resources/hibernate.properties
@@ -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
diff --git a/persistence-modules/hibernate5-mapping/src/test/resources/lifecycle-init.sql b/persistence-modules/hibernate5-mapping/src/test/resources/lifecycle-init.sql
new file mode 100644
index 0000000000..c0c9a3f34d
--- /dev/null
+++ b/persistence-modules/hibernate5-mapping/src/test/resources/lifecycle-init.sql
@@ -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);
\ No newline at end of file
diff --git a/persistence-modules/hibernate5-mapping/src/test/resources/profile.png b/persistence-modules/hibernate5-mapping/src/test/resources/profile.png
new file mode 100644
index 0000000000..1cd4e978b9
Binary files /dev/null and b/persistence-modules/hibernate5-mapping/src/test/resources/profile.png differ