diff --git a/persistence-modules/java-jpa-3/pom.xml b/persistence-modules/java-jpa-3/pom.xml
index da18ae3046..7c02cc6c8e 100644
--- a/persistence-modules/java-jpa-3/pom.xml
+++ b/persistence-modules/java-jpa-3/pom.xml
@@ -27,7 +27,21 @@
h2
${h2.version}
-
+
+ mysql
+ mysql-connector-java
+ 8.0.21
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.11.3
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-hibernate5
+ 2.9.8
+
javax.persistence
diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/ignorable/fields/HibernateConfig.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/ignorable/fields/HibernateConfig.java
new file mode 100644
index 0000000000..f5608db8d7
--- /dev/null
+++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/ignorable/fields/HibernateConfig.java
@@ -0,0 +1,40 @@
+package com.baeldung.ignorable.fields;
+
+import java.util.Properties;
+
+import org.hibernate.SessionFactory;
+import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.service.ServiceRegistry;
+
+public class HibernateConfig {
+ private static SessionFactory sessionFactory;
+
+ public static SessionFactory getSessionFactory() {
+ if (sessionFactory == null) {
+ try {
+ Configuration configuration = new Configuration();
+
+ Properties settings = new Properties();
+ settings.put(Environment.DRIVER, "com.mysql.cj.jdbc.Driver");
+ settings.put(Environment.URL, "jdbc:mysql://localhost:3306/app_db?useSSL=false");
+ settings.put(Environment.USER, "root");
+ settings.put(Environment.PASS, "password");
+ settings.put(Environment.DIALECT, "org.hibernate.dialect.MySQL5Dialect");
+ settings.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread");
+ configuration.setProperties(settings);
+
+ configuration.addAnnotatedClass(User.class);
+
+ ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties())
+ .build();
+
+ sessionFactory = configuration.buildSessionFactory(serviceRegistry);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return sessionFactory;
+ }
+}
\ No newline at end of file
diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/ignorable/fields/User.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/ignorable/fields/User.java
new file mode 100644
index 0000000000..0789b93b75
--- /dev/null
+++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/ignorable/fields/User.java
@@ -0,0 +1,80 @@
+package com.baeldung.ignorable.fields;
+
+import java.io.Serializable;
+import java.util.StringJoiner;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "Users")
+public class User implements Serializable {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Integer id;
+ private String email;
+ private String password;
+ @Transient
+ private String currentDevice;
+
+ // Needed for Hibernate mapping
+ public User() {
+ }
+
+ public User(String email, String password, String currentDevice) {
+ this.email = email;
+ this.password = password;
+ this.currentDevice = currentDevice;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getCurrentDevice() {
+ return currentDevice;
+ }
+
+ public void setCurrentDevice(String currentDevice) {
+ this.currentDevice = currentDevice;
+ }
+
+ @Override
+ public String toString() {
+ return new StringJoiner(", ", User.class.getSimpleName() + "[", "]").add("id=" + id)
+ .add("email='" + email + "'")
+ .add("password='" + password + "'")
+ .add("currentDevice='" + currentDevice + "'")
+ .toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (!(o instanceof User))
+ return false;
+ User user = (User) o;
+ return email.equals(user.email);
+ }
+}
\ No newline at end of file
diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/ignorable/fields/UserDao.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/ignorable/fields/UserDao.java
new file mode 100644
index 0000000000..f923968ef4
--- /dev/null
+++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/ignorable/fields/UserDao.java
@@ -0,0 +1,32 @@
+package com.baeldung.ignorable.fields;
+
+import java.util.List;
+
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+
+public class UserDao {
+
+ public void saveUser(User user) {
+ Transaction transaction = null;
+ try (Session session = HibernateConfig.getSessionFactory()
+ .openSession()) {
+ transaction = session.beginTransaction();
+ session.save(user);
+ transaction.commit();
+ } catch (Exception e) {
+ e.printStackTrace();
+ if (transaction != null) {
+ transaction.rollback();
+ }
+ }
+ }
+
+ public List getUsers() {
+ try (Session session = HibernateConfig.getSessionFactory()
+ .openSession()) {
+ return session.createQuery("from User", User.class)
+ .list();
+ }
+ }
+}
diff --git a/persistence-modules/java-jpa-3/src/test/java/com/baeldung/ignorable/fields/TransientFieldTest.java b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/ignorable/fields/TransientFieldTest.java
new file mode 100644
index 0000000000..221bc9bfed
--- /dev/null
+++ b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/ignorable/fields/TransientFieldTest.java
@@ -0,0 +1,79 @@
+package com.baeldung.ignorable.fields;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+import java.io.*;
+import java.util.List;
+import java.util.Random;
+
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.MapperFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;
+
+public class TransientFieldTest {
+
+ private final UserDao userDao = new UserDao();
+
+ private final int randInt = new Random().nextInt();
+
+ private final User user = new User("user" + randInt + "@bar.com", "hunter2", "MacOSX");
+
+ @Test
+ public void JPA_UserWithTransientAnnotation_FieldNotPersisted() {
+ userDao.saveUser(user);
+ List allUsers = userDao.getUsers();
+ User savedUser = allUsers.get(allUsers.indexOf(user));
+
+ assertNull(savedUser.getCurrentDevice());
+ }
+
+ @Test
+ public void JavaSerialization_UserWithTransientAnnotation_FieldSerialized() throws IOException, ClassNotFoundException {
+
+ FileOutputStream fout = new FileOutputStream("test.obj");
+ ObjectOutputStream out = new ObjectOutputStream(fout);
+ out.writeObject(user);
+ out.flush();
+ out.close();
+
+ FileInputStream fin = new FileInputStream("test.obj");
+ ObjectInputStream in = new ObjectInputStream(fin);
+ User savedUser = (User) in.readObject();
+ in.close();
+
+ assertEquals(user.getCurrentDevice(), savedUser.getCurrentDevice());
+ }
+
+ @Test
+ public void JSONSerialization_UserWithTransientAnnotation_FieldSerialized() throws JsonProcessingException {
+ ObjectMapper objectMapper = new ObjectMapper();
+ String json = objectMapper.writeValueAsString(user);
+ User savedUser = objectMapper.readValue(json, User.class);
+
+ assertEquals(user.getCurrentDevice(), savedUser.getCurrentDevice());
+ }
+
+ @Test
+ public void JSONSerialization_JacksonUsingHibernate5Module_FieldNotSerialized() throws JsonProcessingException {
+ ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.registerModule(new Hibernate5Module());
+ String json = objectMapper.writeValueAsString(user);
+ User savedUser = objectMapper.readValue(json, User.class);
+
+ assertNull(savedUser.getCurrentDevice());
+ }
+
+ @Test
+ public void JSONSerialization_MapperPropagatesTransientMarker_FieldSerialized() throws JsonProcessingException {
+ ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);
+ String json = objectMapper.writeValueAsString(user);
+ User savedUser = objectMapper.readValue(json, User.class);
+
+ assertEquals(user.getCurrentDevice(), savedUser.getCurrentDevice());
+ }
+}