diff --git a/patterns/design-patterns/pom.xml b/patterns/design-patterns/pom.xml
index 87db08ab32..abf449fc43 100644
--- a/patterns/design-patterns/pom.xml
+++ b/patterns/design-patterns/pom.xml
@@ -12,41 +12,63 @@
..
-
+
junit
junit
4.12
test
-
- org.hamcrest
- hamcrest-core
- 1.3
- test
+
+ org.hamcrest
+ hamcrest-core
+ 1.3
+ test
org.assertj
assertj-core
- 3.8.0
+ 3.9.1
test
+
+ org.mockito
+ mockito-core
+ 2.18.3
+ test
+
+
+ javax
+ javaee-api
+ 8.0
+
+
+ org.hibernate
+ hibernate-core
+ 5.2.16.Final
+
+
+ mysql
+ mysql-connector-java
+ 8.0.11
+ test
+
- log4j
- log4j
- ${log4j.version}
-
-
- com.googlecode.grep4j
- grep4j
- ${grep4j.version}
-
+ log4j
+ log4j
+ ${log4j.version}
+
+
+ com.googlecode.grep4j
+ grep4j
+ ${grep4j.version}
+
UTF-8
1.8
1.8
1.2.17
- 1.8.7
+ 1.8.7
-
\ No newline at end of file
+
diff --git a/patterns/design-patterns/src/main/java/com/baeldung/daopattern/application/UserApplication.java b/patterns/design-patterns/src/main/java/com/baeldung/daopattern/application/UserApplication.java
new file mode 100644
index 0000000000..05155aafcd
--- /dev/null
+++ b/patterns/design-patterns/src/main/java/com/baeldung/daopattern/application/UserApplication.java
@@ -0,0 +1,52 @@
+package com.baeldung.daopattern.application;
+
+import com.baeldung.daopattern.daos.Dao;
+import com.baeldung.daopattern.daos.JpaUserDao;
+import com.baeldung.daopattern.entities.User;
+import java.util.List;
+import java.util.Optional;
+import javax.persistence.EntityManager;
+import javax.persistence.Persistence;
+
+public class UserApplication {
+
+ private static JpaUserDao jpaUserDao;
+
+ public static void main(String[] args) {
+ User user1 = getUser(1);
+ System.out.println(user1);
+ updateUser(user1, new String[]{"John", "john@domain.com"});
+ saveUser(new User("Monica", "monica@domain.com"));
+ deleteUser(getUser(2));
+ getAllUsers().forEach(user -> System.out.println(user.getName()));
+ }
+
+ public static Dao getJpaUserDao() {
+ if (jpaUserDao == null) {
+ EntityManager entityManager = Persistence.createEntityManagerFactory("user-unit").createEntityManager();
+ jpaUserDao = new JpaUserDao(entityManager);
+ }
+ return jpaUserDao;
+ }
+
+ public static User getUser(long id) {
+ Optional user = getJpaUserDao().get(id);
+ return user.orElse(new User("Non-existing user", "no-email"));
+ }
+
+ public static List getAllUsers() {
+ return getJpaUserDao().getAll();
+ }
+
+ public static void updateUser(User user, String[] params){
+ getJpaUserDao().update(user, params);
+ }
+
+ public static void saveUser(User user) {
+ getJpaUserDao().save(user);
+ }
+
+ public static void deleteUser(User user) {
+ getJpaUserDao().delete(user);
+ }
+}
diff --git a/patterns/design-patterns/src/main/java/com/baeldung/daopattern/daos/Dao.java b/patterns/design-patterns/src/main/java/com/baeldung/daopattern/daos/Dao.java
new file mode 100644
index 0000000000..35aa763097
--- /dev/null
+++ b/patterns/design-patterns/src/main/java/com/baeldung/daopattern/daos/Dao.java
@@ -0,0 +1,17 @@
+package com.baeldung.daopattern.daos;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface Dao {
+
+ Optional get(long id);
+
+ List getAll();
+
+ void save(T t);
+
+ void update(T t, String[] params);
+
+ void delete(T t);
+}
diff --git a/patterns/design-patterns/src/main/java/com/baeldung/daopattern/daos/JpaUserDao.java b/patterns/design-patterns/src/main/java/com/baeldung/daopattern/daos/JpaUserDao.java
new file mode 100644
index 0000000000..f4d80c0ee9
--- /dev/null
+++ b/patterns/design-patterns/src/main/java/com/baeldung/daopattern/daos/JpaUserDao.java
@@ -0,0 +1,60 @@
+package com.baeldung.daopattern.daos;
+
+import com.baeldung.daopattern.entities.User;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Consumer;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityTransaction;
+import javax.persistence.Query;
+
+public class JpaUserDao implements Dao {
+
+ private final EntityManager entityManager;
+
+ public JpaUserDao(EntityManager entityManager) {
+ this.entityManager = entityManager;
+ }
+
+ @Override
+ public Optional get(long id) {
+ return Optional.ofNullable(entityManager.find(User.class, id));
+ }
+
+ @Override
+ public List getAll() {
+ Query query = entityManager.createQuery("SELECT e FROM User e");
+ return query.getResultList();
+ }
+
+ @Override
+ public void save(User user) {
+ executeInsideTransaction(entityManager -> entityManager.persist(user));
+ }
+
+ @Override
+ public void update(User user, String[] params) {
+ user.setName(Objects.requireNonNull(params[0], "Name cannot be null"));
+ user.setEmail(Objects.requireNonNull(params[1], "Email cannot be null"));
+ executeInsideTransaction(entityManager -> entityManager.merge(user));
+ }
+
+ @Override
+ public void delete(User user) {
+ executeInsideTransaction(entityManager -> entityManager.remove(user));
+ }
+
+ private void executeInsideTransaction(Consumer action) {
+ final EntityTransaction tx = entityManager.getTransaction();
+ try {
+ tx.begin();
+ action.accept(entityManager);
+ tx.commit();
+ }
+ catch (RuntimeException e) {
+ tx.rollback();
+ throw e;
+ }
+ }
+}
diff --git a/patterns/design-patterns/src/main/java/com/baeldung/daopattern/daos/UserDao.java b/patterns/design-patterns/src/main/java/com/baeldung/daopattern/daos/UserDao.java
new file mode 100644
index 0000000000..2fd4047772
--- /dev/null
+++ b/patterns/design-patterns/src/main/java/com/baeldung/daopattern/daos/UserDao.java
@@ -0,0 +1,44 @@
+package com.baeldung.daopattern.daos;
+
+import com.baeldung.daopattern.entities.User;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+public class UserDao implements Dao {
+
+ private List users = new ArrayList<>();
+
+ public UserDao() {
+ users.add(new User("John", "john@domain.com"));
+ users.add(new User("Susan", "susan@domain.com"));
+ }
+
+ @Override
+ public Optional get(long id) {
+ return Optional.ofNullable(users.get((int) id));
+ }
+
+ @Override
+ public List getAll() {
+ return users;
+ }
+
+ @Override
+ public void save(User user) {
+ users.add(user);
+ }
+
+ @Override
+ public void update(User user, String[] params) {
+ user.setName(Objects.requireNonNull(params[0], "Name cannot be null"));
+ user.setEmail(Objects.requireNonNull(params[1], "Email cannot be null"));
+ users.add(user);
+ }
+
+ @Override
+ public void delete(User user) {
+ users.remove(user);
+ }
+}
diff --git a/patterns/design-patterns/src/main/java/com/baeldung/daopattern/entities/User.java b/patterns/design-patterns/src/main/java/com/baeldung/daopattern/entities/User.java
new file mode 100644
index 0000000000..58d8ffb28b
--- /dev/null
+++ b/patterns/design-patterns/src/main/java/com/baeldung/daopattern/entities/User.java
@@ -0,0 +1,45 @@
+package com.baeldung.daopattern.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/patterns/design-patterns/src/main/resources/META-INF/persistence.xml b/patterns/design-patterns/src/main/resources/META-INF/persistence.xml
new file mode 100644
index 0000000000..61a5c9effc
--- /dev/null
+++ b/patterns/design-patterns/src/main/resources/META-INF/persistence.xml
@@ -0,0 +1,17 @@
+
+
+
+ org.hibernate.jpa.HibernatePersistenceProvider
+ com.baeldung.daopattern.entities.User
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/patterns/design-patterns/src/test/java/com/baeldung/daopattern/test/UserDaoUnitTest.java b/patterns/design-patterns/src/test/java/com/baeldung/daopattern/test/UserDaoUnitTest.java
new file mode 100644
index 0000000000..683e626600
--- /dev/null
+++ b/patterns/design-patterns/src/test/java/com/baeldung/daopattern/test/UserDaoUnitTest.java
@@ -0,0 +1,53 @@
+package com.baeldung.daopattern.test;
+
+import com.baeldung.daopattern.daos.UserDao;
+import com.baeldung.daopattern.entities.User;
+import java.util.List;
+import java.util.Optional;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class UserDaoUnitTest {
+
+ private static UserDao userDao;
+
+
+ @BeforeClass
+ public static void setUpUserDaoInstance() {
+ userDao = new UserDao();
+ }
+
+ @Test
+ public void givenUserDaoInstance_whenCalledget_thenOneAssertion() {
+ assertThat(userDao.get(0)).isInstanceOf(Optional.class);
+ }
+
+ @Test
+ public void givenUserDaoInstance_whenCalledgetAll_thenOneAssertion() {
+ assertThat(userDao.getAll()).isInstanceOf(List.class);
+ }
+
+ @Test
+ public void givenUserDaoInstance_whenCalledupdate_thenTwoAssertions() {
+ User user = new User("Julie", "julie@domain.com");
+ userDao.update(user, new String[] {"Julie", "julie@domain.com"});
+ assertThat(userDao.get(2).get().getName()).isEqualTo("Julie");
+ assertThat(userDao.get(2).get().getEmail()).isEqualTo("julie@domain.com");
+ }
+
+ @Test
+ public void givenUserDaoInstance_whenCalledsave_thenTwoAssertions() {
+ User user = new User("Julie", "julie@domain.com");
+ userDao.save(user);
+ assertThat(userDao.get(2).get().getName()).isEqualTo("Julie");
+ assertThat(userDao.get(2).get().getEmail()).isEqualTo("julie@domain.com");
+ }
+
+ @Test
+ public void givenUserDaoInstance_whenCalleddelete_thenOneAssertion() {
+ User user = new User("Julie", "julie@domain.com");
+ userDao.delete(user);
+ assertThat(userDao.getAll().size()).isEqualTo(2);
+ }
+}