diff --git a/persistence-modules/hibernate5-jpa/README.md b/persistence-modules/hibernate5-jpa/README.md new file mode 100644 index 0000000000..bffba85d54 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/README.md @@ -0,0 +1,16 @@ +## Hibernate 5 + +This module contains articles about Hibernate 5. + +### Relevant articles: + +- [JPA Attribute Converters](http://www.baeldung.com/jpa-attribute-converters) +- [Pessimistic Locking in JPA](http://www.baeldung.com/jpa-pessimistic-locking) +- [Bootstrapping JPA Programmatically in Java](http://www.baeldung.com/java-bootstrap-jpa) +- [Optimistic Locking in JPA](http://www.baeldung.com/jpa-optimistic-locking) +- [Criteria API – An Example of IN Expressions](https://www.baeldung.com/jpa-criteria-api-in-expressions) +- [One-to-One Relationship in JPA](https://www.baeldung.com/jpa-one-to-one) +- [Enabling Transaction Locks in Spring Data JPA](https://www.baeldung.com/java-jpa-transaction-locks) +- [TransactionRequiredException Error](https://www.baeldung.com/jpa-transaction-required-exception) +- [FetchMode in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-fetchmode) +- [JPA/Hibernate Persistence Context](https://www.baeldung.com/jpa-hibernate-persistence-context) diff --git a/persistence-modules/hibernate5-jpa/pom.xml b/persistence-modules/hibernate5-jpa/pom.xml new file mode 100644 index 0000000000..b181fff36b --- /dev/null +++ b/persistence-modules/hibernate5-jpa/pom.xml @@ -0,0 +1,95 @@ + + + 4.0.0 + hibernate5-jpa + 0.0.1-SNAPSHOT + hibernate5-jpa + + + com.baeldung + persistence-modules + 1.0.0-SNAPSHOT + + + + + org.hibernate + hibernate-core + ${hibernate.version} + + + org.springframework.boot + spring-boot-starter-web + ${spring-boot.version} + + + org.springframework.boot + spring-boot-starter-thymeleaf + ${spring-boot.version} + + + org.springframework.boot + spring-boot-starter-data-jpa + ${spring-boot.version} + + + com.zaxxer + HikariCP + + + + + org.springframework.boot + spring-boot-starter-test + ${spring-boot.version} + + + org.assertj + assertj-core + ${assertj-core.version} + test + + + com.h2database + h2 + ${h2.version} + + + org.hibernate + hibernate-spatial + ${hibernate.version} + + + mysql + mysql-connector-java + ${mysql.version} + + + ch.vorburger.mariaDB4j + mariaDB4j + ${mariaDB4j.version} + + + org.hibernate + hibernate-testing + ${hibernate.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${openjdk-jmh.version} + + + + + 5.3.7.Final + 6.0.6 + 2.2.3 + 3.8.0 + 1.21 + 2.1.7.RELEASE + + + diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/HibernateUtil.java new file mode 100644 index 0000000000..cf59fe4855 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/HibernateUtil.java @@ -0,0 +1,89 @@ +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.optimisticlocking.OptimisticLockingCourse; +import com.baeldung.hibernate.optimisticlocking.OptimisticLockingStudent; +import com.baeldung.hibernate.pessimisticlocking.Individual; +import com.baeldung.hibernate.pessimisticlocking.PessimisticLockingCourse; +import com.baeldung.hibernate.pessimisticlocking.PessimisticLockingEmployee; +import com.baeldung.hibernate.pessimisticlocking.PessimisticLockingStudent; +import com.baeldung.hibernate.pojo.Person; +import com.baeldung.hibernate.pojo.Post; +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(Person.class); + metadataSources.addAnnotatedClass(Student.class); + metadataSources.addAnnotatedClass(Individual.class); + metadataSources.addAnnotatedClass(PessimisticLockingEmployee.class); + metadataSources.addAnnotatedClass(PessimisticLockingStudent.class); + metadataSources.addAnnotatedClass(PessimisticLockingCourse.class); + metadataSources.addAnnotatedClass(com.baeldung.hibernate.pessimisticlocking.Customer.class); + metadataSources.addAnnotatedClass(com.baeldung.hibernate.pessimisticlocking.Address.class); + metadataSources.addAnnotatedClass(DeptEmployee.class); + metadataSources.addAnnotatedClass(com.baeldung.hibernate.entities.Department.class); + metadataSources.addAnnotatedClass(OptimisticLockingCourse.class); + metadataSources.addAnnotatedClass(OptimisticLockingStudent.class); + metadataSources.addAnnotatedClass(Post.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-jpa/src/main/java/com/baeldung/hibernate/UnsupportedTenancyException.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/UnsupportedTenancyException.java new file mode 100644 index 0000000000..99d9505ea3 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/UnsupportedTenancyException.java @@ -0,0 +1,8 @@ +package com.baeldung.hibernate; + +public class UnsupportedTenancyException extends Exception { + public UnsupportedTenancyException (String message) { + super(message); + } + +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/converters/PersonNameConverter.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/converters/PersonNameConverter.java new file mode 100644 index 0000000000..506e674984 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/converters/PersonNameConverter.java @@ -0,0 +1,61 @@ +package com.baeldung.hibernate.converters; + +import javax.persistence.AttributeConverter; +import javax.persistence.Converter; + +import com.baeldung.hibernate.pojo.PersonName; + +@Converter +public class PersonNameConverter implements AttributeConverter { + + private static final String SEPARATOR = ", "; + + @Override + public String convertToDatabaseColumn(PersonName personName) { + if (personName == null) { + return null; + } + + StringBuilder sb = new StringBuilder(); + if (personName.getSurname() != null && !personName.getSurname() + .isEmpty()) { + sb.append(personName.getSurname()); + sb.append(SEPARATOR); + } + + if (personName.getName() != null && !personName.getName() + .isEmpty()) { + sb.append(personName.getName()); + } + + return sb.toString(); + } + + @Override + public PersonName convertToEntityAttribute(String dbPersonName) { + if (dbPersonName == null || dbPersonName.isEmpty()) { + return null; + } + + String[] pieces = dbPersonName.split(SEPARATOR); + + if (pieces == null || pieces.length == 0) { + return null; + } + + PersonName personName = new PersonName(); + String firstPiece = !pieces[0].isEmpty() ? pieces[0] : null; + if (dbPersonName.contains(SEPARATOR)) { + personName.setSurname(firstPiece); + + if (pieces.length >= 2 && pieces[1] != null && !pieces[1].isEmpty()) { + personName.setName(pieces[1]); + } + } else { + personName.setName(firstPiece); + } + + return personName; + } + +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/entities/Department.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/entities/Department.java new file mode 100644 index 0000000000..ff94f4f849 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/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-jpa/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java new file mode 100644 index 0000000000..6510e70650 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/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-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/application/Application.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/application/Application.java new file mode 100644 index 0000000000..f7b8e6bf6d --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/application/Application.java @@ -0,0 +1,34 @@ +package com.baeldung.hibernate.jpabootstrap.application; + +import com.baeldung.hibernate.jpabootstrap.config.JpaEntityManagerFactory; +import com.baeldung.hibernate.jpabootstrap.entities.User; +import javax.persistence.EntityManager; + +public class Application { + + public static void main(String[] args) { + EntityManager entityManager = getJpaEntityManager(); + User user = entityManager.find(User.class, 1); + System.out.println(user); + entityManager.getTransaction().begin(); + user.setName("John"); + user.setEmail("john@domain.com"); + entityManager.merge(user); + entityManager.getTransaction().commit(); + entityManager.getTransaction().begin(); + entityManager.persist(new User("Monica", "monica@domain.com")); + entityManager.getTransaction().commit(); + + // additional CRUD operations + + } + + private static class EntityManagerHolder { + private static final EntityManager ENTITY_MANAGER = new JpaEntityManagerFactory( + new Class[]{User.class}).getEntityManager(); + } + + public static EntityManager getJpaEntityManager() { + return EntityManagerHolder.ENTITY_MANAGER; + } +} \ No newline at end of file diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/config/HibernatePersistenceUnitInfo.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/config/HibernatePersistenceUnitInfo.java new file mode 100644 index 0000000000..3852b44b64 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/config/HibernatePersistenceUnitInfo.java @@ -0,0 +1,131 @@ +package com.baeldung.hibernate.jpabootstrap.config; + +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Properties; +import javax.sql.DataSource; +import javax.persistence.SharedCacheMode; +import javax.persistence.ValidationMode; +import javax.persistence.spi.ClassTransformer; +import javax.persistence.spi.PersistenceUnitInfo; +import javax.persistence.spi.PersistenceUnitTransactionType; +import org.hibernate.jpa.HibernatePersistenceProvider; + +public class HibernatePersistenceUnitInfo implements PersistenceUnitInfo { + + public static final String JPA_VERSION = "2.1"; + private final String persistenceUnitName; + private PersistenceUnitTransactionType transactionType = PersistenceUnitTransactionType.RESOURCE_LOCAL; + private final List managedClassNames; + private final List mappingFileNames = new ArrayList<>(); + private final Properties properties; + private DataSource jtaDataSource; + private DataSource nonjtaDataSource; + private final List transformers = new ArrayList<>(); + + public HibernatePersistenceUnitInfo(String persistenceUnitName, List managedClassNames, Properties properties) { + this.persistenceUnitName = persistenceUnitName; + this.managedClassNames = managedClassNames; + this.properties = properties; + } + + @Override + public String getPersistenceUnitName() { + return persistenceUnitName; + } + + @Override + public String getPersistenceProviderClassName() { + return HibernatePersistenceProvider.class.getName(); + } + + @Override + public PersistenceUnitTransactionType getTransactionType() { + return transactionType; + } + + public HibernatePersistenceUnitInfo setJtaDataSource(DataSource jtaDataSource) { + this.jtaDataSource = jtaDataSource; + this.nonjtaDataSource = null; + transactionType = PersistenceUnitTransactionType.JTA; + return this; + } + + @Override + public DataSource getJtaDataSource() { + return jtaDataSource; + } + + public HibernatePersistenceUnitInfo setNonJtaDataSource(DataSource nonJtaDataSource) { + this.nonjtaDataSource = nonJtaDataSource; + this.jtaDataSource = null; + transactionType = PersistenceUnitTransactionType.RESOURCE_LOCAL; + return this; + } + + @Override + public DataSource getNonJtaDataSource() { + return nonjtaDataSource; + } + + @Override + public List getMappingFileNames() { + return mappingFileNames; + } + + @Override + public List getJarFileUrls() { + return Collections.emptyList(); + } + + @Override + public URL getPersistenceUnitRootUrl() { + return null; + } + + @Override + public List getManagedClassNames() { + return managedClassNames; + } + + @Override + public boolean excludeUnlistedClasses() { + return false; + } + + @Override + public SharedCacheMode getSharedCacheMode() { + return SharedCacheMode.UNSPECIFIED; + } + + @Override + public ValidationMode getValidationMode() { + return ValidationMode.AUTO; + } + + public Properties getProperties() { + return properties; + } + + @Override + public String getPersistenceXMLSchemaVersion() { + return JPA_VERSION; + } + + @Override + public ClassLoader getClassLoader() { + return Thread.currentThread().getContextClassLoader(); + } + + @Override + public void addTransformer(ClassTransformer transformer) { + transformers.add(transformer); + } + + @Override + public ClassLoader getNewTempClassLoader() { + return null; + } +} \ No newline at end of file diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/config/JpaEntityManagerFactory.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/config/JpaEntityManagerFactory.java new file mode 100644 index 0000000000..bc1932af6f --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/config/JpaEntityManagerFactory.java @@ -0,0 +1,69 @@ +package com.baeldung.hibernate.jpabootstrap.config; + +import com.mysql.cj.jdbc.MysqlDataSource; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.stream.Collectors; +import javax.persistence.EntityManager; +import javax.sql.DataSource; +import javax.persistence.EntityManagerFactory; +import javax.persistence.spi.PersistenceUnitInfo; +import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl; +import org.hibernate.jpa.boot.internal.PersistenceUnitInfoDescriptor; + +public class JpaEntityManagerFactory { + + private final String DB_URL = "jdbc:mysql://databaseurl"; + private final String DB_USER_NAME = "username"; + private final String DB_PASSWORD = "password"; + private final Class[] entityClasses; + + public JpaEntityManagerFactory(Class[] entityClasses) { + this.entityClasses = entityClasses; + } + + public EntityManager getEntityManager() { + return getEntityManagerFactory().createEntityManager(); + } + + protected EntityManagerFactory getEntityManagerFactory() { + PersistenceUnitInfo persistenceUnitInfo = getPersistenceUnitInfo(getClass().getSimpleName()); + Map configuration = new HashMap<>(); + return new EntityManagerFactoryBuilderImpl(new PersistenceUnitInfoDescriptor(persistenceUnitInfo), configuration) + .build(); + } + + protected HibernatePersistenceUnitInfo getPersistenceUnitInfo(String name) { + return new HibernatePersistenceUnitInfo(name, getEntityClassNames(), getProperties()); + } + + protected List getEntityClassNames() { + return Arrays.asList(getEntities()) + .stream() + .map(Class::getName) + .collect(Collectors.toList()); + } + + protected Properties getProperties() { + Properties properties = new Properties(); + properties.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect"); + properties.put("hibernate.id.new_generator_mappings", false); + properties.put("hibernate.connection.datasource", getMysqlDataSource()); + return properties; + } + + protected Class[] getEntities() { + return entityClasses; + } + + protected DataSource getMysqlDataSource() { + MysqlDataSource mysqlDataSource = new MysqlDataSource(); + mysqlDataSource.setURL(DB_URL); + mysqlDataSource.setUser(DB_USER_NAME); + mysqlDataSource.setPassword(DB_PASSWORD); + return mysqlDataSource; + } +} \ No newline at end of file diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/entities/User.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/entities/User.java new file mode 100644 index 0000000000..86ca1dfa19 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/jpabootstrap/entities/User.java @@ -0,0 +1,45 @@ +package com.baeldung.hibernate.jpabootstrap.entities; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "users") +public class User { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; + private String name; + private String email; + + public User(){} + + public User(String name, String email) { + this.name = name; + this.email = email; + } + + public void setName(String name) { + this.name = name; + } + + public void setEmail(String email) { + this.email = email; + } + + public long getId() { + return id; + } + + public String getName() { + return name; + } + + public String getEmail() { + return email; + } +} \ No newline at end of file diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/jpacriteriabuilder/service/EmployeeSearchService.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/jpacriteriabuilder/service/EmployeeSearchService.java new file mode 100644 index 0000000000..b7d1a537f0 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/jpacriteriabuilder/service/EmployeeSearchService.java @@ -0,0 +1,15 @@ +package com.baeldung.hibernate.jpacriteriabuilder.service; + +import java.util.List; + +import com.baeldung.hibernate.entities.DeptEmployee; + +public interface EmployeeSearchService { + + List filterbyTitleUsingCriteriaBuilder(List titles); + + List filterbyTitleUsingExpression(List titles); + + List searchByDepartmentQuery(String query); + +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/jpacriteriabuilder/service/EmployeeSearchServiceImpl.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/jpacriteriabuilder/service/EmployeeSearchServiceImpl.java new file mode 100644 index 0000000000..e79168a451 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/jpacriteriabuilder/service/EmployeeSearchServiceImpl.java @@ -0,0 +1,77 @@ +package com.baeldung.hibernate.jpacriteriabuilder.service; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaBuilder.In; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; +import javax.persistence.criteria.Subquery; + +import com.baeldung.hibernate.entities.Department; +import com.baeldung.hibernate.entities.DeptEmployee; + +public class EmployeeSearchServiceImpl implements EmployeeSearchService { + + private EntityManager entityManager; + private CriteriaBuilder criteriaBuilder; + + public EmployeeSearchServiceImpl(EntityManager entityManager) { + this.entityManager = entityManager; + this.criteriaBuilder = entityManager.getCriteriaBuilder(); + + } + + @Override + public List filterbyTitleUsingCriteriaBuilder(List titles) { + CriteriaQuery criteriaQuery = createCriteriaQuery(DeptEmployee.class); + Root root = criteriaQuery.from(DeptEmployee.class); + In inClause = criteriaBuilder.in(root.get("title")); + for (String title : titles) { + inClause.value(title); + } + criteriaQuery.select(root) + .where(inClause); + TypedQuery query = entityManager.createQuery(criteriaQuery); + return query.getResultList(); + } + + @Override + public List filterbyTitleUsingExpression(List titles) { + CriteriaQuery criteriaQuery = createCriteriaQuery(DeptEmployee.class); + Root root = criteriaQuery.from(DeptEmployee.class); + criteriaQuery.select(root) + .where(root.get("title") + .in(titles)); + TypedQuery query = entityManager.createQuery(criteriaQuery); + return query.getResultList(); + } + + @Override + public List searchByDepartmentQuery(String searchKey) { + CriteriaQuery criteriaQuery = createCriteriaQuery(DeptEmployee.class); + Root emp = criteriaQuery.from(DeptEmployee.class); + + Subquery subquery = criteriaQuery.subquery(Department.class); + Root dept = subquery.from(Department.class); + subquery.select(dept) + .distinct(true) + .where(criteriaBuilder.like(dept.get("name"), new StringBuffer("%").append(searchKey) + .append("%") + .toString())); + + criteriaQuery.select(emp) + .where(criteriaBuilder.in(emp.get("department")) + .value(subquery)); + + TypedQuery query = entityManager.createQuery(criteriaQuery); + return query.getResultList(); + } + + private CriteriaQuery createCriteriaQuery(Class klass) { + return criteriaBuilder.createQuery(klass); + } + +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/HibernateUtil.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/HibernateUtil.java new file mode 100644 index 0000000000..18fa2a41db --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/HibernateUtil.java @@ -0,0 +1,61 @@ +package com.baeldung.hibernate.onetoone; + +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 java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +import java.util.Properties; + +public class HibernateUtil { + private static SessionFactory sessionFactory; + + private HibernateUtil() { + } + + public static SessionFactory getSessionFactory(Strategy strategy) { + return buildSessionFactory(strategy); + } + + private static SessionFactory buildSessionFactory(Strategy strategy) { + try { + ServiceRegistry serviceRegistry = configureServiceRegistry(); + + MetadataSources metadataSources = new MetadataSources(serviceRegistry); + + for (Class entityClass : strategy.getEntityClasses()) { + metadataSources.addAnnotatedClass(entityClass); + } + + Metadata metadata = metadataSources.getMetadataBuilder() + .build(); + + return metadata.getSessionFactoryBuilder() + .build(); + } catch (IOException ex) { + throw new ExceptionInInitializerError(ex); + } + } + + + 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("hibernate.properties"); + try (FileInputStream inputStream = new FileInputStream(propertiesURL.getFile())) { + properties.load(inputStream); + } + return properties; + } +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/Strategy.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/Strategy.java new file mode 100644 index 0000000000..3180566ca5 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/Strategy.java @@ -0,0 +1,25 @@ +package com.baeldung.hibernate.onetoone; + + +import java.util.Arrays; +import java.util.List; + +public enum Strategy { + //See that the classes belongs to different packages + FOREIGN_KEY(Arrays.asList(com.baeldung.hibernate.onetoone.foreignkeybased.User.class, + com.baeldung.hibernate.onetoone.foreignkeybased.Address.class)), + SHARED_PRIMARY_KEY(Arrays.asList(com.baeldung.hibernate.onetoone.sharedkeybased.User.class, + com.baeldung.hibernate.onetoone.sharedkeybased.Address.class)), + JOIN_TABLE_BASED(Arrays.asList(com.baeldung.hibernate.onetoone.jointablebased.Employee.class, + com.baeldung.hibernate.onetoone.jointablebased.WorkStation.class)); + + private List> entityClasses; + + Strategy(List> entityClasses) { + this.entityClasses = entityClasses; + } + + public List> getEntityClasses() { + return entityClasses; + } +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/foreignkeybased/Address.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/foreignkeybased/Address.java new file mode 100644 index 0000000000..e05eb46030 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/foreignkeybased/Address.java @@ -0,0 +1,60 @@ +package com.baeldung.hibernate.onetoone.foreignkeybased; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +@Entity +@Table(name = "address") +public class Address { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id") + private Long id; + + @Column(name = "street") + private String street; + + @Column(name = "city") + private String city; + + @OneToOne(mappedBy = "address") + private User user; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/foreignkeybased/User.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/foreignkeybased/User.java new file mode 100644 index 0000000000..dda972f29c --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/foreignkeybased/User.java @@ -0,0 +1,51 @@ +package com.baeldung.hibernate.onetoone.foreignkeybased; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +@Entity +@Table(name = "users") +public class User { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id") + private Long id; + + @Column(name = "username") + private String userName; + + @OneToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "address_id", referencedColumnName = "id") + private Address address; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/jointablebased/Employee.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/jointablebased/Employee.java new file mode 100644 index 0000000000..a0bc101b9f --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/jointablebased/Employee.java @@ -0,0 +1,53 @@ +package com.baeldung.hibernate.onetoone.jointablebased; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +@Entity +@Table(name = "employee") +public class Employee { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id") + private Long id; + + @Column(name = "ename") + private String name; + + @OneToOne(cascade = CascadeType.ALL) + @JoinTable(name = "emp_workstation", joinColumns = {@JoinColumn(name = "employee_id", referencedColumnName = "id")}, + inverseJoinColumns = {@JoinColumn(name = "workstation_id", referencedColumnName = "id")}) + private WorkStation workStation; + + 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 WorkStation getWorkStation() { + return workStation; + } + + public void setWorkStation(WorkStation workStation) { + this.workStation = workStation; + } +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/jointablebased/WorkStation.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/jointablebased/WorkStation.java new file mode 100644 index 0000000000..f530611f6e --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/jointablebased/WorkStation.java @@ -0,0 +1,61 @@ +package com.baeldung.hibernate.onetoone.jointablebased; + + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +@Entity +@Table(name = "workstation") +public class WorkStation { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id") + private Long id; + + @Column(name = "workstation_number") + private Integer workstationNumber; + + @Column(name = "floor") + private String floor; + + @OneToOne(mappedBy = "workStation") + private Employee employee; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Integer getWorkstationNumber() { + return workstationNumber; + } + + public void setWorkstationNumber(Integer workstationNumber) { + this.workstationNumber = workstationNumber; + } + + public String getFloor() { + return floor; + } + + public void setFloor(String floor) { + this.floor = floor; + } + + public Employee getEmployee() { + return employee; + } + + public void setEmployee(Employee employee) { + this.employee = employee; + } +} \ No newline at end of file diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/sharedkeybased/Address.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/sharedkeybased/Address.java new file mode 100644 index 0000000000..927516f6bb --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/sharedkeybased/Address.java @@ -0,0 +1,60 @@ +package com.baeldung.hibernate.onetoone.sharedkeybased; + + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.MapsId; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +@Entity +@Table(name = "address") +public class Address { + + @Id + @Column(name = "id") + private Long id; + + @Column(name = "street") + private String street; + + @Column(name = "city") + private String city; + + @OneToOne + @MapsId + private User user; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/sharedkeybased/User.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/sharedkeybased/User.java new file mode 100644 index 0000000000..fa00db1271 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/onetoone/sharedkeybased/User.java @@ -0,0 +1,50 @@ +package com.baeldung.hibernate.onetoone.sharedkeybased; + + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +@Entity +@Table(name = "users") +public class User { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id") + private Long id; + + @Column(name = "username") + private String userName; + + @OneToOne(mappedBy = "user", cascade = CascadeType.ALL) + private Address address; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingCourse.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingCourse.java new file mode 100644 index 0000000000..1af3e3e21b --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingCourse.java @@ -0,0 +1,48 @@ +package com.baeldung.hibernate.optimisticlocking; + +import javax.persistence.*; + +@Entity +public class OptimisticLockingCourse { + + @Id + private Long id; + + private String name; + + @ManyToOne + @JoinTable(name = "optimistic_student_course") + private OptimisticLockingStudent student; + + public OptimisticLockingCourse(Long id, String name) { + this.id = id; + this.name = name; + } + + public OptimisticLockingCourse() { + } + + 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 OptimisticLockingStudent getStudent() { + return student; + } + + public void setStudent(OptimisticLockingStudent student) { + this.student = student; + } +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingStudent.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingStudent.java new file mode 100644 index 0000000000..b79212ae8d --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingStudent.java @@ -0,0 +1,70 @@ +package com.baeldung.hibernate.optimisticlocking; + +import javax.persistence.*; +import java.util.List; + +@Entity +public class OptimisticLockingStudent { + + @Id + private Long id; + + private String name; + + private String lastName; + @Version + private Integer version; + + @OneToMany(mappedBy = "student") + private List courses; + + public OptimisticLockingStudent(Long id, String name, String lastName, List courses) { + this.id = id; + this.name = name; + this.lastName = lastName; + this.courses = courses; + } + + public OptimisticLockingStudent() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public List getCourses() { + return courses; + } + + public void setCourses(List courses) { + this.courses = courses; + } +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/Address.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/Address.java new file mode 100644 index 0000000000..c889cb6127 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/Address.java @@ -0,0 +1,34 @@ +package com.baeldung.hibernate.pessimisticlocking; + +import javax.persistence.Embeddable; + +@Embeddable +public class Address { + + private String country; + private String city; + + public Address(String country, String city) { + this.country = country; + this.city = city; + } + + public Address() { + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/Customer.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/Customer.java new file mode 100644 index 0000000000..cb73cbc958 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/Customer.java @@ -0,0 +1,58 @@ +package com.baeldung.hibernate.pessimisticlocking; + +import javax.persistence.*; +import java.util.List; + +@Entity +public class Customer { + + @Id + private Long customerId; + private String name; + private String lastName; + @ElementCollection + @CollectionTable(name = "customer_address") + private List
addressList; + + public Customer() { + } + + public Customer(Long customerId, String name, String lastName, List
addressList) { + this.customerId = customerId; + this.name = name; + this.lastName = lastName; + this.addressList = addressList; + } + + public Long getCustomerId() { + return customerId; + } + + public void setCustomerId(Long customerId) { + this.customerId = customerId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public List
getAddressList() { + return addressList; + } + + public void setAddressList(List
addressList) { + this.addressList = addressList; + } +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/Individual.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/Individual.java new file mode 100644 index 0000000000..e491c09eb5 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/Individual.java @@ -0,0 +1,49 @@ +package com.baeldung.hibernate.pessimisticlocking; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; + +@Entity +@Inheritance(strategy = InheritanceType.JOINED) +public class Individual { + + @Id + private Long id; + private String name; + private String lastName; + + public Individual(Long id, String name, String lastName) { + this.id = id; + this.name = name; + this.lastName = lastName; + } + + public Individual() { + } + + 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 String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingCourse.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingCourse.java new file mode 100644 index 0000000000..aea7d5fc87 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingCourse.java @@ -0,0 +1,47 @@ +package com.baeldung.hibernate.pessimisticlocking; + +import javax.persistence.*; + +@Entity +public class PessimisticLockingCourse { + + @Id + private Long courseId; + private String name; + @ManyToOne + @JoinTable(name = "student_course") + private PessimisticLockingStudent student; + + public PessimisticLockingCourse(Long courseId, String name, PessimisticLockingStudent student) { + this.courseId = courseId; + this.name = name; + this.student = student; + } + + public PessimisticLockingCourse() { + } + + public Long getCourseId() { + return courseId; + } + + public void setCourseId(Long courseId) { + this.courseId = courseId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public PessimisticLockingStudent getStudent() { + return student; + } + + public void setStudent(PessimisticLockingStudent students) { + this.student = students; + } +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingEmployee.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingEmployee.java new file mode 100644 index 0000000000..a1328cbdad --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingEmployee.java @@ -0,0 +1,27 @@ +package com.baeldung.hibernate.pessimisticlocking; + +import javax.persistence.Entity; +import java.math.BigDecimal; + +@Entity +public class PessimisticLockingEmployee extends Individual { + + private BigDecimal salary; + + public PessimisticLockingEmployee(Long id, String name, String lastName, BigDecimal salary) { + super(id, name, lastName); + this.salary = salary; + } + + public PessimisticLockingEmployee() { + super(); + } + + public BigDecimal getSalary() { + return salary; + } + + public void setSalary(BigDecimal average) { + this.salary = average; + } +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingStudent.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingStudent.java new file mode 100644 index 0000000000..e6c5f476b4 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingStudent.java @@ -0,0 +1,46 @@ +package com.baeldung.hibernate.pessimisticlocking; + +import javax.persistence.*; +import java.util.List; + +@Entity +public class PessimisticLockingStudent { + + @Id + private Long id; + private String name; + @OneToMany(mappedBy = "student") + private List courses; + + public PessimisticLockingStudent(Long id, String name) { + this.id = id; + this.name = name; + } + + public PessimisticLockingStudent() { + } + + 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 getCourses() { + return courses; + } + + public void setCourses(List courses) { + this.courses = courses; + } +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pojo/Movie.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pojo/Movie.java new file mode 100644 index 0000000000..5fae7f6a97 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pojo/Movie.java @@ -0,0 +1,52 @@ +package com.baeldung.hibernate.pojo; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "MOVIE") +public class Movie { + + @Id + private Long id; + + private String movieName; + + private Integer releaseYear; + + private String language; + + public String getMovieName() { + return movieName; + } + + public void setMovieName(String movieName) { + this.movieName = movieName; + } + + public Integer getReleaseYear() { + return releaseYear; + } + + public void setReleaseYear(Integer releaseYear) { + this.releaseYear = releaseYear; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pojo/Person.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pojo/Person.java new file mode 100644 index 0000000000..390a5954ed --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pojo/Person.java @@ -0,0 +1,32 @@ +package com.baeldung.hibernate.pojo; + +import javax.persistence.Convert; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +import com.baeldung.hibernate.converters.PersonNameConverter; + +@Entity(name = "PersonTable") +public class Person { + + @Id + @GeneratedValue + private Long id; + + @Convert(converter = PersonNameConverter.class) + private PersonName personName; + + public PersonName getPersonName() { + return personName; + } + + public void setPersonName(PersonName personName) { + this.personName = personName; + } + + public Long getId() { + return id; + } + +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pojo/PersonName.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pojo/PersonName.java new file mode 100644 index 0000000000..335fe73f75 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pojo/PersonName.java @@ -0,0 +1,29 @@ +package com.baeldung.hibernate.pojo; + +import java.io.Serializable; + +public class PersonName implements Serializable { + + private static final long serialVersionUID = 7883094644631050150L; + + private String name; + + private String surname; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSurname() { + return surname; + } + + public void setSurname(String surname) { + this.surname = surname; + } + +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pojo/Post.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pojo/Post.java new file mode 100644 index 0000000000..25e51e35d0 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pojo/Post.java @@ -0,0 +1,59 @@ +package com.baeldung.hibernate.pojo; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "posts") +public class Post { + + @Id + @GeneratedValue + private int id; + + private String title; + + private String body; + + public Post() { } + + public Post(String title, String body) { + this.title = title; + this.body = body; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getBody() { + return body; + } + + public void setBody(String body) { + this.body = body; + } + + @Override + public String toString() { + return "Post{" + + "id=" + id + + ", title='" + title + '\'' + + ", body='" + body + '\'' + + '}'; + } +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pojo/Student.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pojo/Student.java new file mode 100644 index 0000000000..9b26c117eb --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/pojo/Student.java @@ -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; + } + +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/transaction/PostService.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/transaction/PostService.java new file mode 100644 index 0000000000..5a4eb20079 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/hibernate/transaction/PostService.java @@ -0,0 +1,29 @@ +package com.baeldung.hibernate.transaction; + +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.hibernate.query.Query; + +public class PostService { + + + private Session session; + + public PostService(Session session) { + this.session = session; + } + + + public void updatePost(String title, String body, int id) { + Transaction txn = session.beginTransaction(); + Query updateQuery = session.createQuery("UPDATE Post p SET p.title = ?1, p.body = ?2 WHERE p.id = ?3"); + updateQuery.setParameter(1, title); + updateQuery.setParameter(2, body); + updateQuery.setParameter(3, id); + updateQuery.executeUpdate(); + txn.commit(); + } + + + +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/persistencecontext/PersistenceContextDemoApplication.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/persistencecontext/PersistenceContextDemoApplication.java new file mode 100644 index 0000000000..17fa582e10 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/persistencecontext/PersistenceContextDemoApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.persistencecontext; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +@ComponentScan(basePackages="com.baeldung.persistencecontext") +public class PersistenceContextDemoApplication { + public static void main(String[] args) { + SpringApplication.run(PersistenceContextDemoApplication.class, args); + } +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/persistencecontext/entity/User.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/persistencecontext/entity/User.java new file mode 100644 index 0000000000..7252ac46f5 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/persistencecontext/entity/User.java @@ -0,0 +1,36 @@ +package com.baeldung.persistencecontext.entity; + +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class User { + + @Id + private Long id; + private String name; + private String role; + + public User() { + + } + + public User(Long id, String name, String role) { + this.id = id; + this.name = name; + this.role = role; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public String getRole() { + return role; + } + +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/persistencecontext/service/ExtendedPersistenceContextUserService.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/persistencecontext/service/ExtendedPersistenceContextUserService.java new file mode 100644 index 0000000000..ef25aac69f --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/persistencecontext/service/ExtendedPersistenceContextUserService.java @@ -0,0 +1,33 @@ +package com.baeldung.persistencecontext.service; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.PersistenceContextType; +import javax.transaction.Transactional; + +import org.springframework.stereotype.Component; + +import com.baeldung.persistencecontext.entity.User; + +@Component +public class ExtendedPersistenceContextUserService { + + @PersistenceContext(type = PersistenceContextType.EXTENDED) + private EntityManager entityManager; + + @Transactional + public User insertWithTransaction(User user) { + entityManager.persist(user); + return user; + } + + public User insertWithoutTransaction(User user) { + entityManager.persist(user); + return user; + } + + public User find(long id) { + User user = entityManager.find(User.class, id); + return user; + } +} diff --git a/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/persistencecontext/service/TransctionPersistenceContextUserService.java b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/persistencecontext/service/TransctionPersistenceContextUserService.java new file mode 100644 index 0000000000..481defcf08 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/java/com/baeldung/persistencecontext/service/TransctionPersistenceContextUserService.java @@ -0,0 +1,32 @@ +package com.baeldung.persistencecontext.service; + + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.transaction.Transactional; + +import org.springframework.stereotype.Component; + +import com.baeldung.persistencecontext.entity.User; + +@Component +public class TransctionPersistenceContextUserService { + + @PersistenceContext + private EntityManager entityManager; + + @Transactional + public User insertWithTransaction(User user) { + entityManager.persist(user); + return user; + } + + public User insertWithoutTransaction(User user) { + entityManager.persist(user); + return user; + } + + public User find(long id) { + return entityManager.find(User.class, id); + } +} diff --git a/persistence-modules/hibernate5-jpa/src/main/resources/META-INF/persistence.xml b/persistence-modules/hibernate5-jpa/src/main/resources/META-INF/persistence.xml new file mode 100644 index 0000000000..4dfade1af3 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,19 @@ + + + + Hibernate EntityManager Demo + com.baeldung.hibernate.pojo.Movie + true + + + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/hibernate5-jpa/src/main/resources/init_database.sql b/persistence-modules/hibernate5-jpa/src/main/resources/init_database.sql new file mode 100644 index 0000000000..b2848aa256 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/main/resources/init_database.sql @@ -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(); +} +$$; \ No newline at end of file diff --git a/persistence-modules/hibernate5-jpa/src/main/resources/logback.xml b/persistence-modules/hibernate5-jpa/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/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-jpa/src/test/java/com/baeldung/hibernate/converter/PersonNameConverterUnitTest.java b/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/converter/PersonNameConverterUnitTest.java new file mode 100644 index 0000000000..3cd4761a7b --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/converter/PersonNameConverterUnitTest.java @@ -0,0 +1,200 @@ +package com.baeldung.hibernate.converter; + +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.HibernateUtil; +import com.baeldung.hibernate.pojo.Person; +import com.baeldung.hibernate.pojo.PersonName; + +import static org.junit.Assert.assertEquals; + +public class PersonNameConverterUnitTest { + + private Session session; + private Transaction transaction; + + @Before + public void setUp() throws IOException { + session = HibernateUtil.getSessionFactory() + .openSession(); + transaction = session.beginTransaction(); + + session.createNativeQuery("delete from personTable") + .executeUpdate(); + + transaction.commit(); + transaction = session.beginTransaction(); + } + + @After + public void tearDown() { + transaction.rollback(); + session.close(); + } + + @Test + public void givenPersonName_WhenSaving_ThenNameAndSurnameConcat() { + final String name = "name"; + final String surname = "surname"; + + PersonName personName = new PersonName(); + personName.setName(name); + personName.setSurname(surname); + + Person person = new Person(); + person.setPersonName(personName); + + Long id = (Long) session.save(person); + + session.flush(); + session.clear(); + + String dbPersonName = (String) session.createNativeQuery("select p.personName from PersonTable p where p.id = :id") + .setParameter("id", id) + .getSingleResult(); + + assertEquals(surname + ", " + name, dbPersonName); + + Person dbPerson = session.createNativeQuery("select * from PersonTable p where p.id = :id", Person.class) + .setParameter("id", id) + .getSingleResult(); + + assertEquals(dbPerson.getPersonName() + .getName(), name); + assertEquals(dbPerson.getPersonName() + .getSurname(), surname); + } + + @Test + public void givenPersonNameNull_WhenSaving_ThenNullStored() { + final String name = null; + final String surname = null; + + PersonName personName = new PersonName(); + personName.setName(name); + personName.setSurname(surname); + + Person person = new Person(); + person.setPersonName(personName); + + Long id = (Long) session.save(person); + + session.flush(); + session.clear(); + + String dbPersonName = (String) session.createNativeQuery("select p.personName from PersonTable p where p.id = :id") + .setParameter("id", id) + .getSingleResult(); + + assertEquals("", dbPersonName); + + Person dbPerson = session.createNativeQuery("select * from PersonTable p where p.id = :id", Person.class) + .setParameter("id", id) + .getSingleResult(); + + assertEquals(dbPerson.getPersonName(), null); + } + + @Test + public void givenPersonNameWithoutName_WhenSaving_ThenNotNameStored() { + final String name = null; + final String surname = "surname"; + + PersonName personName = new PersonName(); + personName.setName(name); + personName.setSurname(surname); + + Person person = new Person(); + person.setPersonName(personName); + + Long id = (Long) session.save(person); + + session.flush(); + session.clear(); + + String dbPersonName = (String) session.createNativeQuery("select p.personName from PersonTable p where p.id = :id") + .setParameter("id", id) + .getSingleResult(); + + assertEquals("surname, ", dbPersonName); + + Person dbPerson = session.createNativeQuery("select * from PersonTable p where p.id = :id", Person.class) + .setParameter("id", id) + .getSingleResult(); + + assertEquals(dbPerson.getPersonName() + .getName(), name); + assertEquals(dbPerson.getPersonName() + .getSurname(), surname); + } + + @Test + public void givenPersonNameWithoutSurName_WhenSaving_ThenNotSurNameStored() { + final String name = "name"; + final String surname = null; + + PersonName personName = new PersonName(); + personName.setName(name); + personName.setSurname(surname); + + Person person = new Person(); + person.setPersonName(personName); + + Long id = (Long) session.save(person); + + session.flush(); + session.clear(); + + String dbPersonName = (String) session.createNativeQuery("select p.personName from PersonTable p where p.id = :id") + .setParameter("id", id) + .getSingleResult(); + + assertEquals("name", dbPersonName); + + Person dbPerson = session.createNativeQuery("select * from PersonTable p where p.id = :id", Person.class) + .setParameter("id", id) + .getSingleResult(); + + assertEquals(dbPerson.getPersonName() + .getName(), name); + assertEquals(dbPerson.getPersonName() + .getSurname(), surname); + } + + @Test + public void givenPersonNameEmptyFields_WhenSaving_ThenFielsNotStored() { + final String name = ""; + final String surname = ""; + + PersonName personName = new PersonName(); + personName.setName(name); + personName.setSurname(surname); + + Person person = new Person(); + person.setPersonName(personName); + + Long id = (Long) session.save(person); + + session.flush(); + session.clear(); + + String dbPersonName = (String) session.createNativeQuery("select p.personName from PersonTable p where p.id = :id") + .setParameter("id", id) + .getSingleResult(); + + assertEquals("", dbPersonName); + + Person dbPerson = session.createNativeQuery("select * from PersonTable p where p.id = :id", Person.class) + .setParameter("id", id) + .getSingleResult(); + + assertEquals(dbPerson.getPersonName(), null); + } + +} diff --git a/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/jpacriteriabuilder/EmployeeSearchServiceIntegrationTest.java b/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/jpacriteriabuilder/EmployeeSearchServiceIntegrationTest.java new file mode 100644 index 0000000000..2b12734a10 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/jpacriteriabuilder/EmployeeSearchServiceIntegrationTest.java @@ -0,0 +1,121 @@ +package com.baeldung.hibernate.jpacriteriabuilder; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder; +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import javax.persistence.EntityManager; + +import org.hibernate.HibernateException; +import org.hibernate.Session; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.baeldung.hibernate.HibernateUtil; +import com.baeldung.hibernate.entities.Department; +import com.baeldung.hibernate.entities.DeptEmployee; +import com.baeldung.hibernate.jpacriteriabuilder.service.EmployeeSearchService; +import com.baeldung.hibernate.jpacriteriabuilder.service.EmployeeSearchServiceImpl; + +public class EmployeeSearchServiceIntegrationTest { + + private EntityManager entityManager; + private EmployeeSearchService searchService; + private Session session; + + @Before + public final void setup() throws HibernateException, IOException { + session = HibernateUtil.getSessionFactory() + .openSession(); + entityManager = session.getEntityManagerFactory() + .createEntityManager(); + searchService = new EmployeeSearchServiceImpl(entityManager); + + entityManager.getTransaction() + .begin(); + Department department = new Department("Pre Sales"); + DeptEmployee employee = new DeptEmployee("John Smith", "001", "Manager", department); + entityManager.persist(department); + entityManager.persist(employee); + employee = new DeptEmployee("Ian Evans", "002", "Associate", department); + entityManager.persist(department); + entityManager.persist(employee); + department = new Department("Copporate Sales"); + employee = new DeptEmployee("Robert Carter", "003", "Manager", department); + entityManager.persist(department); + entityManager.persist(employee); + employee = new DeptEmployee("John Carter", "004", "Senior Manager", department); + entityManager.persist(employee); + employee = new DeptEmployee("David Guetta", "009", "Associate", department); + entityManager.persist(department); + entityManager.persist(employee); + department = new Department("Post Sales"); + employee = new DeptEmployee("Robert Jonas", "005", "Director", department); + entityManager.persist(department); + entityManager.persist(employee); + employee = new DeptEmployee("John Ferros", "006", "Junior Associate", department); + entityManager.persist(department); + entityManager.persist(employee); + department = new Department("Client Support"); + employee = new DeptEmployee("Robert Mcclements", "007", "Director", department); + entityManager.persist(department); + entityManager.persist(employee); + employee = new DeptEmployee("Peter Parker", "008", "Manager", department); + entityManager.persist(department); + entityManager.persist(employee); + + } + + @After + public final void teardown() { + entityManager.getTransaction() + .rollback(); + entityManager.close(); + } + + @Test + public final void givenCriteriaQuery_whenSearchedUsingCriteriaBuilderWithListofAuthors_thenResultIsFilteredByAuthorNames() { + List titles = new ArrayList() { + { + add("Manager"); + add("Senior Manager"); + add("Director"); + } + }; + List result = searchService.filterbyTitleUsingCriteriaBuilder(titles); + assertEquals("Number of Employees does not match with expected.", 6, result.size()); + assertThat(result.stream() + .map(DeptEmployee::getTitle) + .distinct() + .collect(Collectors.toList()), containsInAnyOrder(titles.toArray())); + } + + @Test + public final void givenCriteriaQuery_whenSearchedUsingExpressionWithListofAuthors_thenResultIsFilteredByAuthorNames() { + List titles = new ArrayList() { + { + add("Manager"); + add("Senior Manager"); + add("Director"); + } + }; + List result = searchService.filterbyTitleUsingExpression(titles); + assertEquals("Number of Employees does not match with expected.", 6, result.size()); + assertThat(result.stream() + .map(DeptEmployee::getTitle) + .distinct() + .collect(Collectors.toList()), containsInAnyOrder(titles.toArray())); + } + + @Test + public final void givenCriteriaQuery_whenSearchedDepartmentLike_thenResultIsFilteredByDepartment() { + List result = searchService.searchByDepartmentQuery("Sales"); + assertEquals("Number of Employees does not match with expected.", 7, result.size()); + } +} diff --git a/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/onetoone/HibernateOneToOneAnnotationFKBasedIntegrationTest.java b/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/onetoone/HibernateOneToOneAnnotationFKBasedIntegrationTest.java new file mode 100644 index 0000000000..475c93f6ff --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/onetoone/HibernateOneToOneAnnotationFKBasedIntegrationTest.java @@ -0,0 +1,80 @@ +package com.baeldung.hibernate.onetoone; + +import com.baeldung.hibernate.onetoone.foreignkeybased.Address; +import com.baeldung.hibernate.onetoone.foreignkeybased.User; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class HibernateOneToOneAnnotationFKBasedIntegrationTest { + + private static SessionFactory sessionFactory; + + private Session session; + + @BeforeClass + public static void beforeTests() { + sessionFactory = HibernateUtil.getSessionFactory(Strategy.FOREIGN_KEY); + } + + @Before + public void setUp() { + session = sessionFactory.openSession(); + session.beginTransaction(); + } + + @Test + public void givenData_whenInsert_thenCreates1to1relationship() { + User user = new User(); + user.setUserName("alice@baeldung.com"); + + Address address = new Address(); + address.setStreet("FK Street"); + address.setCity("FK City"); + + address.setUser(user); + user.setAddress(address); + + //Address entry will automatically be created by hibernate, since cascade type is specified as ALL + session.persist(user); + session.getTransaction().commit(); + + assert1to1InsertedData(); + } + + private void assert1to1InsertedData() { + @SuppressWarnings("unchecked") + List userList = session.createQuery("FROM User").list(); + + assertNotNull(userList); + assertEquals(1, userList.size()); + + User user = userList.get(0); + assertEquals("alice@baeldung.com", user.getUserName()); + + Address address = user.getAddress(); + assertNotNull(address); + assertEquals("FK Street", address.getStreet()); + assertEquals("FK City", address.getCity()); + + } + + @After + public void tearDown() { + session.close(); + } + + @AfterClass + public static void afterTests() { + sessionFactory.close(); + } +} diff --git a/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/onetoone/HibernateOneToOneAnnotationJTBasedIntegrationTest.java b/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/onetoone/HibernateOneToOneAnnotationJTBasedIntegrationTest.java new file mode 100644 index 0000000000..df4cd4d137 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/onetoone/HibernateOneToOneAnnotationJTBasedIntegrationTest.java @@ -0,0 +1,80 @@ +package com.baeldung.hibernate.onetoone; + +import com.baeldung.hibernate.onetoone.jointablebased.Employee; +import com.baeldung.hibernate.onetoone.jointablebased.WorkStation; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class HibernateOneToOneAnnotationJTBasedIntegrationTest { + + private static SessionFactory sessionFactory; + + private Session session; + + @BeforeClass + public static void beforeTests() { + sessionFactory = HibernateUtil.getSessionFactory(Strategy.JOIN_TABLE_BASED); + } + + @Before + public void setUp() { + session = sessionFactory.openSession(); + session.beginTransaction(); + } + + @Test + public void givenData_whenInsert_thenCreates1to1relationship() { + Employee employee = new Employee(); + employee.setName("bob@baeldung.com"); + + WorkStation workStation = new WorkStation(); + workStation.setWorkstationNumber(626); + workStation.setFloor("Sixth Floor"); + + + employee.setWorkStation(workStation); + workStation.setEmployee(employee); + + session.persist(employee); + session.getTransaction().commit(); + + assert1to1InsertedData(); + } + + private void assert1to1InsertedData() { + @SuppressWarnings("unchecked") + List employeeList = session.createQuery("FROM Employee").list(); + assertNotNull(employeeList); + assertEquals(1, employeeList.size()); + + Employee employee = employeeList.get(0); + assertEquals("bob@baeldung.com", employee.getName()); + + WorkStation workStation = employee.getWorkStation(); + + assertNotNull(workStation); + assertEquals((long) 626, (long) workStation.getWorkstationNumber()); + assertEquals("Sixth Floor", workStation.getFloor()); + + } + + @After + public void tearDown() { + session.close(); + } + + @AfterClass + public static void afterTests() { + sessionFactory.close(); + } +} diff --git a/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/onetoone/HibernateOneToOneAnnotationSPKBasedIntegrationTest.java b/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/onetoone/HibernateOneToOneAnnotationSPKBasedIntegrationTest.java new file mode 100644 index 0000000000..7931a8e3fe --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/onetoone/HibernateOneToOneAnnotationSPKBasedIntegrationTest.java @@ -0,0 +1,79 @@ +package com.baeldung.hibernate.onetoone; + +import com.baeldung.hibernate.onetoone.sharedkeybased.Address; +import com.baeldung.hibernate.onetoone.sharedkeybased.User; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class HibernateOneToOneAnnotationSPKBasedIntegrationTest { + + private static SessionFactory sessionFactory; + + private Session session; + + @BeforeClass + public static void beforeTests() { + sessionFactory = HibernateUtil.getSessionFactory(Strategy.SHARED_PRIMARY_KEY); + } + + @Before + public void setUp() { + session = sessionFactory.openSession(); + session.beginTransaction(); + } + + @Test + public void givenData_whenInsert_thenCreates1to1relationship() { + User user = new User(); + user.setUserName("alice@baeldung.com"); + + Address address = new Address(); + address.setStreet("SPK Street"); + address.setCity("SPK City"); + + address.setUser(user); + user.setAddress(address); + + //Address entry will automatically be created by hibernate, since cascade type is specified as ALL + session.persist(user); + session.getTransaction().commit(); + + assert1to1InsertedData(); + } + + + private void assert1to1InsertedData() { + @SuppressWarnings("unchecked") + List userList = session.createQuery("FROM User").list(); + assertNotNull(userList); + assertEquals(1, userList.size()); + + User user = userList.get(0); + assertEquals("alice@baeldung.com", user.getUserName()); + + Address address = user.getAddress(); + assertNotNull(address); + assertEquals("SPK Street", address.getStreet()); + assertEquals("SPK City", address.getCity()); + } + + @After + public void tearDown() { + session.close(); + } + + @AfterClass + public static void afterTests() { + sessionFactory.close(); + } +} diff --git a/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingIntegrationTest.java b/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingIntegrationTest.java new file mode 100644 index 0000000000..37c490f297 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingIntegrationTest.java @@ -0,0 +1,146 @@ +package com.baeldung.hibernate.optimisticlocking; + +import java.io.IOException; +import java.util.Arrays; + +import javax.persistence.EntityManager; +import javax.persistence.LockModeType; +import javax.persistence.OptimisticLockException; + +import org.hibernate.SessionFactory; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; + +import com.baeldung.hibernate.HibernateUtil; + +public class OptimisticLockingIntegrationTest { + + private static SessionFactory sessionFactory; + + @Before + public void setUp() throws IOException { + EntityManager entityManager = getEntityManagerWithOpenTransaction(); + OptimisticLockingCourse course = new OptimisticLockingCourse(1L, "MATH"); + OptimisticLockingStudent student = new OptimisticLockingStudent(1L, "John", "Doe", Arrays.asList(course)); + course.setStudent(student); + entityManager.persist(course); + entityManager.persist(student); + entityManager.getTransaction() + .commit(); + entityManager.close(); + } + + @After + public void clean() throws IOException { + EntityManager entityManager = getEntityManagerWithOpenTransaction(); + OptimisticLockingCourse course = entityManager.find(OptimisticLockingCourse.class, 1L); + OptimisticLockingStudent student = entityManager.find(OptimisticLockingStudent.class, 1L); + entityManager.remove(course); + entityManager.remove(student); + entityManager.getTransaction() + .commit(); + entityManager.close(); + } + + @Test(expected = OptimisticLockException.class) + public void givenVersionedEntities_whenConcurrentUpdate_thenOptimisticLockException() throws IOException { + EntityManager em = getEntityManagerWithOpenTransaction(); + OptimisticLockingStudent student = em.find(OptimisticLockingStudent.class, 1L); + + EntityManager em2 = getEntityManagerWithOpenTransaction(); + OptimisticLockingStudent student2 = em2.find(OptimisticLockingStudent.class, 1L); + student2.setName("RICHARD"); + em2.persist(student2); + em2.getTransaction() + .commit(); + em2.close(); + + student.setName("JOHN"); + em.persist(student); + em.getTransaction() + .commit(); + em.close(); + } + + @Test(expected = OptimisticLockException.class) + public void givenVersionedEntitiesWithLockByFindMethod_whenConcurrentUpdate_thenOptimisticLockException() throws IOException { + EntityManager em = getEntityManagerWithOpenTransaction(); + OptimisticLockingStudent student = em.find(OptimisticLockingStudent.class, 1L, LockModeType.OPTIMISTIC); + + EntityManager em2 = getEntityManagerWithOpenTransaction(); + OptimisticLockingStudent student2 = em2.find(OptimisticLockingStudent.class, 1L, LockModeType.OPTIMISTIC_FORCE_INCREMENT); + student2.setName("RICHARD"); + em2.persist(student2); + em2.getTransaction() + .commit(); + em2.close(); + + student.setName("JOHN"); + em.persist(student); + em.getTransaction() + .commit(); + em.close(); + } + + @Test(expected = OptimisticLockException.class) + public void givenVersionedEntitiesWithLockByRefreshMethod_whenConcurrentUpdate_thenOptimisticLockException() throws IOException { + EntityManager em = getEntityManagerWithOpenTransaction(); + OptimisticLockingStudent student = em.find(OptimisticLockingStudent.class, 1L); + em.refresh(student, LockModeType.OPTIMISTIC); + + EntityManager em2 = getEntityManagerWithOpenTransaction(); + OptimisticLockingStudent student2 = em2.find(OptimisticLockingStudent.class, 1L); + em.refresh(student, LockModeType.OPTIMISTIC_FORCE_INCREMENT); + student2.setName("RICHARD"); + em2.persist(student2); + em2.getTransaction() + .commit(); + em2.close(); + + student.setName("JOHN"); + em.persist(student); + em.getTransaction() + .commit(); + em.close(); + } + + @Test(expected = OptimisticLockException.class) + public void givenVersionedEntitiesWithLockByLockMethod_whenConcurrentUpdate_thenOptimisticLockException() throws IOException { + EntityManager em = getEntityManagerWithOpenTransaction(); + OptimisticLockingStudent student = em.find(OptimisticLockingStudent.class, 1L); + em.lock(student, LockModeType.OPTIMISTIC); + + EntityManager em2 = getEntityManagerWithOpenTransaction(); + OptimisticLockingStudent student2 = em2.find(OptimisticLockingStudent.class, 1L); + em.lock(student, LockModeType.OPTIMISTIC_FORCE_INCREMENT); + student2.setName("RICHARD"); + em2.persist(student2); + em2.getTransaction() + .commit(); + em2.close(); + + student.setName("JOHN"); + em.persist(student); + em.getTransaction() + .commit(); + em.close(); + } + + protected static EntityManager getEntityManagerWithOpenTransaction() throws IOException { + String propertyFileName = "hibernate-pessimistic-locking.properties"; + if (sessionFactory == null) { + sessionFactory = HibernateUtil.getSessionFactory(propertyFileName); + } + EntityManager entityManager = sessionFactory.openSession(); + entityManager.getTransaction().begin(); + + return entityManager; + } + + @AfterClass + public static void afterTests() { + sessionFactory.close(); + } +} diff --git a/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/pessimisticlocking/BasicPessimisticLockingIntegrationTest.java b/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/pessimisticlocking/BasicPessimisticLockingIntegrationTest.java new file mode 100644 index 0000000000..4b9c7720fd --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/pessimisticlocking/BasicPessimisticLockingIntegrationTest.java @@ -0,0 +1,162 @@ +package com.baeldung.hibernate.pessimisticlocking; + +import com.baeldung.hibernate.HibernateUtil; +import com.vividsolutions.jts.util.Assert; + +import org.hibernate.SessionFactory; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import javax.persistence.*; +import java.io.IOException; +import java.util.Arrays; + +public class BasicPessimisticLockingIntegrationTest { + + private static SessionFactory sessionFactory; + + @BeforeClass + public static void setUp() throws IOException { + EntityManager entityManager = getEntityManagerWithOpenTransaction(); + PessimisticLockingStudent student = new PessimisticLockingStudent(1L, "JOHN"); + PessimisticLockingCourse course = new PessimisticLockingCourse(1L, "MATH", student); + student.setCourses(Arrays.asList(course)); + entityManager.persist(course); + entityManager.persist(student); + entityManager.getTransaction() + .commit(); + entityManager.close(); + } + + @Test + public void givenFoundRecordWithPessimisticRead_whenFindingNewOne_PessimisticLockExceptionThrown() { + try { + EntityManager entityManager = getEntityManagerWithOpenTransaction(); + entityManager.find(PessimisticLockingStudent.class, 1L, LockModeType.PESSIMISTIC_READ); + + EntityManager entityManager2 = getEntityManagerWithOpenTransaction(); + entityManager2.find(PessimisticLockingStudent.class, 1L, LockModeType.PESSIMISTIC_READ); + + entityManager.close(); + entityManager2.close(); + } catch (Exception e) { + Assert.isTrue(e instanceof PessimisticLockException); + } + } + + @Test + public void givenRecordWithPessimisticReadQuery_whenQueryingNewOne_PessimisticLockExceptionThrown() throws IOException { + try { + EntityManager entityManager = getEntityManagerWithOpenTransaction(); + Query query = entityManager.createQuery("from Student where studentId = :studentId"); + query.setParameter("studentId", 1L); + query.setLockMode(LockModeType.PESSIMISTIC_WRITE); + query.getResultList(); + + EntityManager entityManager2 = getEntityManagerWithOpenTransaction(); + Query query2 = entityManager2.createQuery("from Student where studentId = :studentId"); + query2.setParameter("studentId", 1L); + query2.setLockMode(LockModeType.PESSIMISTIC_READ); + query2.getResultList(); + + entityManager.close(); + entityManager2.close(); + } catch (Exception e) { + Assert.isTrue(e instanceof PessimisticLockException); + } + } + + @Test + public void givenRecordWithPessimisticReadLock_whenFindingNewOne_PessimisticLockExceptionThrown() { + try { + EntityManager entityManager = getEntityManagerWithOpenTransaction(); + PessimisticLockingStudent resultStudent = entityManager.find(PessimisticLockingStudent.class, 1L); + entityManager.lock(resultStudent, LockModeType.PESSIMISTIC_READ); + + EntityManager entityManager2 = getEntityManagerWithOpenTransaction(); + entityManager2.find(PessimisticLockingStudent.class, 1L, LockModeType.PESSIMISTIC_FORCE_INCREMENT); + + entityManager.close(); + entityManager2.close(); + } catch (Exception e) { + Assert.isTrue(e instanceof PessimisticLockException); + } + } + + @Test + public void givenRecordAndRefreshWithPessimisticRead_whenFindingWithPessimisticWrite_PessimisticLockExceptionThrown() { + try { + EntityManager entityManager = getEntityManagerWithOpenTransaction(); + PessimisticLockingStudent resultStudent = entityManager.find(PessimisticLockingStudent.class, 1L); + entityManager.refresh(resultStudent, LockModeType.PESSIMISTIC_FORCE_INCREMENT); + + EntityManager entityManager2 = getEntityManagerWithOpenTransaction(); + entityManager2.find(PessimisticLockingStudent.class, 1L, LockModeType.PESSIMISTIC_WRITE); + + entityManager.close(); + entityManager2.close(); + } catch (Exception e) { + Assert.isTrue(e instanceof PessimisticLockException); + } + } + + @Test + public void givenRecordWithPessimisticRead_whenUpdatingRecord_PessimisticLockExceptionThrown() { + try { + EntityManager entityManager = getEntityManagerWithOpenTransaction(); + PessimisticLockingStudent resultStudent = entityManager.find(PessimisticLockingStudent.class, 1L); + entityManager.refresh(resultStudent, LockModeType.PESSIMISTIC_READ); + + EntityManager entityManager2 = getEntityManagerWithOpenTransaction(); + PessimisticLockingStudent resultStudent2 = entityManager2.find(PessimisticLockingStudent.class, 1L); + resultStudent2.setName("Change"); + entityManager2.persist(resultStudent2); + entityManager2.getTransaction() + .commit(); + + entityManager.close(); + entityManager2.close(); + } catch (Exception e) { + Assert.isTrue(e instanceof PessimisticLockException); + } + } + + @Test + public void givenRecordWithPessimisticWrite_whenUpdatingRecord_PessimisticLockExceptionThrown() { + try { + EntityManager entityManager = getEntityManagerWithOpenTransaction(); + PessimisticLockingStudent resultStudent = entityManager.find(PessimisticLockingStudent.class, 1L); + entityManager.refresh(resultStudent, LockModeType.PESSIMISTIC_WRITE); + + EntityManager entityManager2 = getEntityManagerWithOpenTransaction(); + PessimisticLockingStudent resultStudent2 = entityManager2.find(PessimisticLockingStudent.class, 1L); + resultStudent2.setName("Change"); + entityManager2.persist(resultStudent2); + entityManager2.getTransaction() + .commit(); + + entityManager.close(); + entityManager2.close(); + } catch (Exception e) { + Assert.isTrue(e instanceof PessimisticLockException); + } + } + + protected static EntityManager getEntityManagerWithOpenTransaction() throws IOException { + String propertyFileName = "hibernate-pessimistic-locking.properties"; + if (sessionFactory == null) { + sessionFactory = HibernateUtil.getSessionFactory(propertyFileName); + } + EntityManager entityManager = sessionFactory.openSession(); + entityManager.getTransaction().begin(); + + return entityManager; + } + + @AfterClass + public static void afterTests() { + sessionFactory.close(); + } + +} diff --git a/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockScopesIntegrationTest.java b/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockScopesIntegrationTest.java new file mode 100644 index 0000000000..81cb7d95f8 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockScopesIntegrationTest.java @@ -0,0 +1,125 @@ +package com.baeldung.hibernate.pessimisticlocking; + +import com.baeldung.hibernate.HibernateUtil; + +import org.hibernate.SessionFactory; +import org.junit.AfterClass; +import org.junit.Test; + +import javax.persistence.EntityManager; +import javax.persistence.LockModeType; +import javax.persistence.PessimisticLockScope; +import java.io.IOException; +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +public class PessimisticLockScopesIntegrationTest { + + private static SessionFactory sessionFactory; + + @Test + public void givenEclipseEntityWithJoinInheritance_whenNormalLock_thenShouldChildAndParentEntity() throws IOException { + EntityManager em = getEntityManagerWithOpenTransaction(); + PessimisticLockingEmployee employee = new PessimisticLockingEmployee(1L, "JOHN", "SMITH", new BigDecimal(4.5)); + em.persist(employee); + em.getTransaction() + .commit(); + em.close(); + + // NORMAL SCOPE + EntityManager em2 = getEntityManagerWithOpenTransaction(); + PessimisticLockingEmployee foundEmployee = em2.find(PessimisticLockingEmployee.class, 1L, LockModeType.PESSIMISTIC_WRITE); + em2.getTransaction() + .rollback(); + + // EXTENDED SCOPE + Map map = new HashMap<>(); + map.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED); + + EntityManager em3 = getEntityManagerWithOpenTransaction(); + foundEmployee = em3.find(PessimisticLockingEmployee.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); + em3.getTransaction() + .rollback(); + + em2.close(); + em3.close(); + } + + @Test + public void givenEntityWithElementCollection_whenLock_thenHibernateExtendedScopeLockOnlyOwningEntity() throws IOException { + EntityManager em = getEntityManagerWithOpenTransaction(); + Address address = new Address("Poland", "Warsaw"); + Customer customer = new Customer(1L, "JOE", "DOE", Arrays.asList(address)); + em.persist(customer); + em.getTransaction() + .commit(); + em.close(); + + // NORMAL SCOPE + EntityManager em2 = getEntityManagerWithOpenTransaction(); + Customer foundCustomer = em2.find(Customer.class, 1L, LockModeType.PESSIMISTIC_WRITE); + em2.getTransaction() + .rollback(); + + // EXTENDED SCOPE + Map map = new HashMap<>(); + map.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED); + + EntityManager em3 = getEntityManagerWithOpenTransaction(); + foundCustomer = em3.find(Customer.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); + em2.getTransaction() + .rollback(); + + em2.close(); + em3.close(); + } + + @Test + public void givenEntityWithOneToMany_whenLock_thenHibernateExtendedScopeLockOnlyOwningEntity() throws IOException { + EntityManager em = getEntityManagerWithOpenTransaction(); + PessimisticLockingStudent student = new PessimisticLockingStudent(1L, "JOE"); + PessimisticLockingCourse course = new PessimisticLockingCourse(1L, "COURSE", student); + student.setCourses(Arrays.asList(course)); + em.persist(course); + em.persist(student); + em.getTransaction() + .commit(); + em.close(); + + // NORMAL SCOPE + EntityManager em2 = getEntityManagerWithOpenTransaction(); + PessimisticLockingCourse foundCourse = em2.find(PessimisticLockingCourse.class, 1L, LockModeType.PESSIMISTIC_WRITE); + em2.getTransaction() + .rollback(); + + // EXTENDED SCOPE + Map map = new HashMap<>(); + map.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED); + + EntityManager em3 = getEntityManagerWithOpenTransaction(); + foundCourse = em3.find(PessimisticLockingCourse.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); + em3.getTransaction() + .rollback(); + + em2.close(); + em3.close(); + } + + protected EntityManager getEntityManagerWithOpenTransaction() throws IOException { + String propertyFileName = "hibernate-pessimistic-locking.properties"; + if (sessionFactory == null) { + sessionFactory = HibernateUtil.getSessionFactory(propertyFileName); + } + EntityManager entityManager = sessionFactory.openSession(); + entityManager.getTransaction().begin(); + + return entityManager; + } + + @AfterClass + public static void afterTests() { + sessionFactory.close(); + } +} diff --git a/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/transaction/TransactionIntegrationTest.java b/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/transaction/TransactionIntegrationTest.java new file mode 100644 index 0000000000..246a7d59f9 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/hibernate/transaction/TransactionIntegrationTest.java @@ -0,0 +1,57 @@ +package com.baeldung.hibernate.transaction; + +import com.baeldung.hibernate.HibernateUtil; +import com.baeldung.hibernate.pojo.Post; +import com.baeldung.hibernate.transaction.PostService; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.junit.BeforeClass; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Properties; + +import static org.junit.Assert.assertEquals; + +public class TransactionIntegrationTest { + + private static PostService postService; + private static Session session; + private static Logger logger = LoggerFactory.getLogger(TransactionIntegrationTest.class); + + @BeforeClass + public static void init() throws IOException { + Properties properties = new Properties(); + properties.setProperty("hibernate.connection.driver_class", "org.h2.Driver"); + properties.setProperty("hibernate.connection.url", "jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1"); + properties.setProperty("hibernate.connection.username", "sa"); + properties.setProperty("hibernate.show_sql", "true"); + properties.setProperty("jdbc.password", ""); + properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect"); + properties.setProperty("hibernate.hbm2ddl.auto", "create-drop"); + SessionFactory sessionFactory = HibernateUtil.getSessionFactoryByProperties(properties); + session = sessionFactory.openSession(); + postService = new PostService(session); + } + + @Test + public void givenTitleAndBody_whenRepositoryUpdatePost_thenUpdatePost() { + + Post post = new Post("This is a title", "This is a sample post"); + session.persist(post); + + String title = "[UPDATE] Java HowTos"; + String body = "This is an updated posts on Java how-tos"; + postService.updatePost(title, body, post.getId()); + + session.refresh(post); + + assertEquals(post.getTitle(), title); + assertEquals(post.getBody(), body); + } + + +} diff --git a/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/persistencecontext/PersistenceContextIntegrationTest.java b/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/persistencecontext/PersistenceContextIntegrationTest.java new file mode 100644 index 0000000000..b299dd5834 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/test/java/com/baeldung/persistencecontext/PersistenceContextIntegrationTest.java @@ -0,0 +1,90 @@ +package com.baeldung.persistencecontext; + +import com.baeldung.persistencecontext.entity.User; +import com.baeldung.persistencecontext.service.ExtendedPersistenceContextUserService; +import com.baeldung.persistencecontext.service.TransctionPersistenceContextUserService; + +import javax.persistence.EntityExistsException; +import javax.persistence.TransactionRequiredException; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = com.baeldung.persistencecontext.PersistenceContextDemoApplication.class) +public class PersistenceContextIntegrationTest { + + @Autowired + private TransctionPersistenceContextUserService transctionPersistenceContext; + @Autowired + private ExtendedPersistenceContextUserService extendedPersistenceContext; + + @Test + public void testThatWhenUserSavedWithTransctionPersistenceContextThenUserShouldGetSavedInDB() { + User user = new User(121L, "Devender", "admin"); + transctionPersistenceContext.insertWithTransaction(user); + + User userFromTransctionPersistenceContext = transctionPersistenceContext.find(user.getId()); + assertNotNull(userFromTransctionPersistenceContext); + + User userFromExtendedPersistenceContext = extendedPersistenceContext.find(user.getId()); + assertNotNull(userFromExtendedPersistenceContext); + } + + @Test(expected = TransactionRequiredException.class) + public void testThatUserSaveWithoutTransactionThrowException() { + User user = new User(122L, "Devender", "admin"); + transctionPersistenceContext.insertWithoutTransaction(user); + } + + @Test + public void testThatWhenUserSavedWithExtendedPersistenceContextWithoutTransactionThenUserShouldGetCached() { + User user = new User(123L, "Devender", "admin"); + extendedPersistenceContext.insertWithoutTransaction(user); + + User userFromExtendedPersistenceContext = extendedPersistenceContext.find(user.getId()); + assertNotNull(userFromExtendedPersistenceContext); + + User userFromTransctionPersistenceContext = transctionPersistenceContext.find(user.getId()); + assertNull(userFromTransctionPersistenceContext); + } + + @Test(expected = EntityExistsException.class) + public void testThatPersistUserWithSameIdentifierThrowException() { + User user1 = new User(126L, "Devender", "admin"); + User user2 = new User(126L, "Devender", "admin"); + extendedPersistenceContext.insertWithoutTransaction(user1); + extendedPersistenceContext.insertWithoutTransaction(user2); + } + + @Test + public void testThatWhenUserSavedWithExtendedPersistenceContextWithTransactionThenUserShouldSaveEntityIntoDB() { + User user = new User(127L, "Devender", "admin"); + extendedPersistenceContext.insertWithTransaction(user); + + User userFromDB = transctionPersistenceContext.find(user.getId()); + assertNotNull(userFromDB); + } + + @Test + public void testThatWhenUserSavedWithExtendedPersistenceContextWithTransactionThenUserShouldFlushCachedEntityIntoDB() { + User user1 = new User(124L, "Devender", "admin"); + extendedPersistenceContext.insertWithoutTransaction(user1); + + User user2 = new User(125L, "Devender", "admin"); + extendedPersistenceContext.insertWithTransaction(user2); + + User user1FromTransctionPersistenceContext = transctionPersistenceContext.find(user1.getId()); + assertNotNull(user1FromTransctionPersistenceContext); + + User user2FromTransctionPersistenceContext = transctionPersistenceContext.find(user2.getId()); + assertNotNull(user2FromTransctionPersistenceContext); + } + +} diff --git a/persistence-modules/hibernate5-jpa/src/test/resources/hibernate-namedquery.properties b/persistence-modules/hibernate5-jpa/src/test/resources/hibernate-namedquery.properties new file mode 100644 index 0000000000..457f965347 --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/test/resources/hibernate-namedquery.properties @@ -0,0 +1,9 @@ +hibernate.connection.driver_class=org.h2.Driver +hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1;INIT=RUNSCRIPT FROM 'src/main/resources/init_database.sql' +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 \ No newline at end of file diff --git a/persistence-modules/hibernate5-jpa/src/test/resources/hibernate-pessimistic-locking.properties b/persistence-modules/hibernate5-jpa/src/test/resources/hibernate-pessimistic-locking.properties new file mode 100644 index 0000000000..4f1ff5e93a --- /dev/null +++ b/persistence-modules/hibernate5-jpa/src/test/resources/hibernate-pessimistic-locking.properties @@ -0,0 +1,8 @@ +hibernate.connection.driver_class=org.h2.Driver +hibernate.connection.url=jdbc:h2:mem:mydb3;DB_CLOSE_DELAY=-1;LOCK_TIMEOUT=100;MVCC=FALSE +hibernate.connection.username=sa +hibernate.connection.autocommit=true +hibernate.dialect=org.hibernate.dialect.H2Dialect + +hibernate.show_sql=true +hibernate.hbm2ddl.auto=create-drop \ No newline at end of file diff --git a/persistence-modules/hibernate5-jpa/src/test/resources/hibernate.properties b/persistence-modules/hibernate5-jpa/src/test/resources/hibernate.properties new file mode 100644 index 0000000000..c14782ce0f --- /dev/null +++ b/persistence-modules/hibernate5-jpa/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-jpa/src/test/resources/profile.png b/persistence-modules/hibernate5-jpa/src/test/resources/profile.png new file mode 100644 index 0000000000..1cd4e978b9 Binary files /dev/null and b/persistence-modules/hibernate5-jpa/src/test/resources/profile.png differ