Repository: iluwatar/java-design-patterns
Issue: Identity Map pattern
Labels: epic: pattern
type: feature

https://www.sourcecodeexamples.net/2018/04/identity-map-pattern.html
https://en.wikipedia.org/wiki/Identity_map_pattern

Issue comments:
@iluwatar Can I take this? I can probably finish this before this Sunday.
⭐ Sure thing! Thanks for your interest in our project 😃 
Hello @iluwatar, @ohbus and @SuperNovaExtrem, I read the links you provided in the issue and I would like to work on this issue.
I found that pull request #1773 already made for this and it is inactive from some time. 
So if this issue is available can I work on this ?
Closed https://github.com/iluwatar/java-design-patterns/pull/1773 due to inactivity. @DhavalsinhChavda the issue is now assigned to you, please proceed.
Sure @iluwatar, I will start working on this.
Hey @iluwatar I would like to work on this pattern. Do you mind assigning it to me.
Ok @u7275858 

Pull request review comments:
```suggestion
title: Identity Field
```
Please use the version from the parent pom.xml
The configuration seems overly verbose. Can you check how maven-assembly-plugin has been configured in the other patterns?
This should be left out. Use the Java version that's coming from the parent pom.xml (11)

Patch that resolved the issue:
diff --git a/identity-field/README.md b/identity-field/README.md
new file mode 100644
index 000000000000..055d6a685b39
--- /dev/null
+++ b/identity-field/README.md
@@ -0,0 +1,64 @@
+---
+layout: pattern
+title: Identity-Field
+folder: identity-field
+permalink: /patterns/identity-fields/
+categories: Structural
+tags:
+- Data access
+---
+
+## Intent
+Saves a database ID field in an object to maintain an identity between an in-memory object and a database row.
+
+## Explanation
+
+In plain words
+
+> It uses a java class that has one field matching the primary key in a database table.
+
+**Programmatic Example**
+
+We have a **person** table which contains **id**, **name**, **age**, and **gender** as columns.
+
+| id |   name   | age | gender |
+| :--------: | :--------: | :--------: | :--------: |
+| 1	 | ramesh   | 28  | male   |
+| 2	 | prakash  | 28  | male   |
+
+We also have a java class **Person** which contains **id**, **name**, **age**, and **gender** as fields.
+
+```java
+class Person{
+    private long id;
+    private String name;
+    private int age;
+    private String gender;
+    // standard getter and setter methods.
+}
+```
+1. **id** column is the **primary key** in a database that is unique and distinguishes each row.
+2. In the above table, there are two rows and which are uniquely identified by the primary key.
+3. The relational database uses the primary key to identify one row from another.
+
+The **id** column with datatype long represents the identity field.
+
+In **Person** java class, the **id** field is an identity field that matches the primary key in a database table.
+
+##Representing the Identity Field in an Object
+
+The simplest form of Identity Field is a field that matches the type of key in the database. Thus, if you use a simple integral key, an integral field will work very nicely.
+
+There are three basic choices to get the key:
+- Get the database to auto-generate
+- Use a GUID
+- Generate your own
+
+## Class diagram
+![alt text](./etc/identity-field.png "identity-field")
+
+## Applicability
+Use the Identity-Field pattern when
+
+* There’s a mapping between objects in memory and rows in a database.
+ 
\ No newline at end of file
diff --git a/identity-field/etc/identity-field.puml b/identity-field/etc/identity-field.puml
new file mode 100644
index 000000000000..c223331f93c9
--- /dev/null
+++ b/identity-field/etc/identity-field.puml
@@ -0,0 +1,17 @@
+@startuml
+package com.iluwatar.identityfield {
+  class App {
+    + App()
+    + main(args : String[]) {static}
+  }
+  class Person {
+    - id : long
+    - name : string
+    + Person(id : long,  name:string)
+    + getName():string
+    + setName(name:string)
+    + getId() : long
+    + setId(id:long)
+  }
+}
+@enduml
\ No newline at end of file
diff --git a/identity-field/pom.xml b/identity-field/pom.xml
new file mode 100644
index 000000000000..e028dfeebdee
--- /dev/null
+++ b/identity-field/pom.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>java-design-patterns</artifactId>
+        <groupId>com.iluwatar</groupId>
+        <version>1.26.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>identity-field</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.22</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifest>
+                            <mainClass>com.test.MainClassName</mainClass>
+                        </manifest>
+                    </archive>
+                    <descriptorRefs>
+                        <descriptorRef>jar-with-dependencies</descriptorRef>
+                    </descriptorRefs>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>make-assembly</id>
+                        <phase>package</phase> <!-- packaging phase -->
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>8</source>
+                    <target>8</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/identity-field/src/main/java/com/iluwatar/identityfield/App.java b/identity-field/src/main/java/com/iluwatar/identityfield/App.java
new file mode 100644
index 000000000000..4d97c029b001
--- /dev/null
+++ b/identity-field/src/main/java/com/iluwatar/identityfield/App.java
@@ -0,0 +1,63 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2021 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.identityfield;
+
+import java.util.LinkedList;
+import lombok.extern.slf4j.Slf4j;
+import lombok.var;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The identity field pattern is used to save a database ID field in an object
+ * to maintain an identity between an in-memory object and a database row.
+ *
+ * <p>In this example, the {@link Person} is used to save each row in the database in a java object.
+ * It uses the field id to identify the row in the database.
+ */
+@Slf4j
+public class App {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
+  /**
+   * The entry point of application.
+   *
+   * @param args the input arguments  、
+   */
+
+  public static void main(String[] args) {
+    var pearsonList = new LinkedList<Person>();
+    for (var i = 0; i < 5; i++) {
+      var name = "pearson" + i;
+      var person = new Person(i, name, i, "male");
+      pearsonList.add(person);
+    }
+    for (var i = 0; i < 5; i++) {
+      LOGGER.info("Id: " + pearsonList.get(i).getId()
+              + " Name: " + pearsonList.get(i).getName()
+              + " Age: " + pearsonList.get(i).getAge()
+              + " Gender: " + pearsonList.get(i).getGender());
+    }
+  }
+}
\ No newline at end of file
diff --git a/identity-field/src/main/java/com/iluwatar/identityfield/Person.java b/identity-field/src/main/java/com/iluwatar/identityfield/Person.java
new file mode 100644
index 000000000000..b5eafd583e22
--- /dev/null
+++ b/identity-field/src/main/java/com/iluwatar/identityfield/Person.java
@@ -0,0 +1,54 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2021 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.identityfield;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * Person is the class to store each row of the table in the database.
+ */
+
+public class Person {
+  @Getter @Setter private long id;
+  @Getter @Setter private String name;
+  @Getter @Setter private int age;
+  @Getter @Setter private String gender;
+
+  /**
+   * Instantiates a new Pearson.
+   *
+   * @param id   the id of the person
+   * @param name the name of the person
+   * @param age  the age of the person
+   * @param gender the gender of the person
+   */
+  public Person(long id, String name, int age, String gender) {
+    this.id = id;
+    this.name = name;
+    this.age = age;
+    this.gender = gender;
+  }
+
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 064e7c1a7eff..b1a503bdac77 100644
--- a/pom.xml
+++ b/pom.xml
@@ -231,6 +231,7 @@
     <module>domain-model</module>
     <module>composite-view</module>
     <module>metadata-mapping</module>
+    <module>identity-field</module>
   </modules>
   <repositories>
     <repository>


Test patch:
diff --git a/identity-field/src/test/java/com/iluwatar/identityfield/AppTest.java b/identity-field/src/test/java/com/iluwatar/identityfield/AppTest.java
new file mode 100644
index 000000000000..955618df68c9
--- /dev/null
+++ b/identity-field/src/test/java/com/iluwatar/identityfield/AppTest.java
@@ -0,0 +1,41 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2021 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.identityfield;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * The type App test.
+ */
+class AppTest {
+  /**
+   * App test.
+   */
+  @Test
+  void shouldExecuteWithoutException() {
+    assertDoesNotThrow(() -> App.main(new String[]{}));
+  }
+}
\ No newline at end of file
diff --git a/identity-field/src/test/java/com/iluwatar/identityfield/PersonTest.java b/identity-field/src/test/java/com/iluwatar/identityfield/PersonTest.java
new file mode 100644
index 000000000000..70d80bbd5d7e
--- /dev/null
+++ b/identity-field/src/test/java/com/iluwatar/identityfield/PersonTest.java
@@ -0,0 +1,89 @@
+/*
+ * The MIT License
+ * Copyright © 2014-2021 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.identityfield;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import lombok.var;
+import org.junit.jupiter.api.Test;
+
+/**
+ * The type Pearson test.
+ */
+class PersonTest {
+  /**
+   * Pearson test.
+   */
+  @Test
+  void setNameTest() {
+    var person = new Person(1, "ramesh", 28, "male");
+    assertEquals(1, person.getId());
+    assertEquals("ramesh", person.getName());
+    assertEquals(28, person.getAge());
+    assertEquals("male", person.getGender());
+    var name = "prakash";
+    person.setName(name);
+    assertEquals("prakash", person.getName());
+    assertEquals(1, person.getId());
+  }
+
+  @Test
+  void setAgeTest() {
+    var person = new Person(1, "ramesh", 28, "male");
+    assertEquals(1, person.getId());
+    assertEquals("ramesh", person.getName());
+    assertEquals(28, person.getAge());
+    assertEquals("male", person.getGender());
+    var age = 29;
+    person.setAge(age);
+    assertEquals(29, person.getAge());
+    assertEquals(1, person.getId());
+  }
+
+  @Test
+  void setGenderTest() {
+    var person = new Person(1, "ramesh", 28, "male");
+    assertEquals(1, person.getId());
+    assertEquals("ramesh", person.getName());
+    assertEquals(28, person.getAge());
+    assertEquals("male", person.getGender());
+    var gender = "female";
+    person.setGender(gender);
+    assertEquals("female", person.getGender());
+    assertEquals(1, person.getId());
+  }
+
+  @Test
+  void setIdTest() {
+    var person = new Person(1, "ramesh", 28, "male");
+    assertEquals(1, person.getId());
+    assertEquals("ramesh", person.getName());
+    assertEquals(28, person.getAge());
+    assertEquals("male", person.getGender());
+    var id = 10;
+    person.setId(id);
+    assertEquals("ramesh", person.getName());
+    assertEquals(10, person.getId());
+  }
+}
\ No newline at end of file