diff --git a/persistence-modules/hibernate-mapping/pom.xml b/persistence-modules/hibernate-mapping/pom.xml
new file mode 100644
index 0000000000..11caf67bf1
--- /dev/null
+++ b/persistence-modules/hibernate-mapping/pom.xml
@@ -0,0 +1,52 @@
+
+
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+ ../../
+
+
+ hibernate-mapping
+ 1.0.0-SNAPSHOT
+ 4.0.0
+
+
+
+ org.hibernate
+ hibernate-core
+ ${hibernate.version}
+
+
+ org.assertj
+ assertj-core
+ ${assertj-core.version}
+ test
+
+
+ com.h2database
+ h2
+ ${h2database.version}
+
+
+
+
+ hibernate-mapping
+
+
+ src/test/resources
+ true
+
+
+
+
+
+ 5.3.7.Final
+ 1.4.196
+ 3.8.0
+
+
+
\ No newline at end of file
diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/HibernateUtil.java
new file mode 100644
index 0000000000..7411edd225
--- /dev/null
+++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/HibernateUtil.java
@@ -0,0 +1,64 @@
+package com.baeldung.hibernate;
+
+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) {
+ if (sessionFactory == null) {
+ sessionFactory = buildSessionFactory(strategy);
+ }
+ return sessionFactory;
+ }
+
+ 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/hibernate-mapping/src/main/java/com/baeldung/hibernate/Strategy.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/Strategy.java
new file mode 100644
index 0000000000..75f10ed583
--- /dev/null
+++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/Strategy.java
@@ -0,0 +1,31 @@
+package com.baeldung.hibernate;
+
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public enum Strategy {
+ //See that the classes belongs to different packages
+ MAP_KEY_COLUMN_BASED(Collections.singletonList(com.baeldung.hibernate.persistmaps.mapkeycolumn.Order.class)),
+ MAP_KEY_BASED(Arrays.asList(com.baeldung.hibernate.persistmaps.mapkey.Item.class,
+ com.baeldung.hibernate.persistmaps.mapkey.Order.class)),
+ MAP_KEY_JOIN_COLUMN_BASED(Arrays.asList(com.baeldung.hibernate.persistmaps.mapkeyjoincolumn.Seller.class,
+ com.baeldung.hibernate.persistmaps.mapkeyjoincolumn.Item.class,
+ com.baeldung.hibernate.persistmaps.mapkeyjoincolumn.Order.class)),
+ MAP_KEY_ENUMERATED_BASED(Arrays.asList(com.baeldung.hibernate.persistmaps.mapkeyenumerated.Order.class,
+ com.baeldung.hibernate.persistmaps.mapkey.Item.class)),
+ MAP_KEY_TEMPORAL_BASED(Arrays.asList(com.baeldung.hibernate.persistmaps.mapkeytemporal.Order.class,
+ com.baeldung.hibernate.persistmaps.mapkey.Item.class));
+
+
+ private List> entityClasses;
+
+ Strategy(List> entityClasses) {
+ this.entityClasses = entityClasses;
+ }
+
+ public List> getEntityClasses() {
+ return entityClasses;
+ }
+}
diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/ItemType.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/ItemType.java
new file mode 100644
index 0000000000..b7f3cef9a2
--- /dev/null
+++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/ItemType.java
@@ -0,0 +1,6 @@
+package com.baeldung.hibernate.persistmaps;
+
+public enum ItemType {
+ JEANS,
+ TSHIRTS
+}
diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Item.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Item.java
new file mode 100644
index 0000000000..385ffe93ea
--- /dev/null
+++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Item.java
@@ -0,0 +1,95 @@
+package com.baeldung.hibernate.persistmaps.mapkey;
+
+import com.baeldung.hibernate.persistmaps.ItemType;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import java.util.Date;
+import java.util.Objects;
+
+@Entity
+@Table(name = "item")
+public class Item {
+ @Id
+ @GeneratedValue
+ @Column(name = "id")
+ private int id;
+
+ @Column(name = "name")
+ private String itemName;
+
+ @Column(name = "price")
+ private double itemPrice;
+
+ @Enumerated(EnumType.STRING)
+ @Column(name = "item_type")
+ private ItemType itemType;
+
+ @Temporal(TemporalType.TIMESTAMP)
+ @Column(name = "created_on")
+ private Date createdOn;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getItemName() {
+ return itemName;
+ }
+
+ public void setItemName(String itemName) {
+ this.itemName = itemName;
+ }
+
+ public double getItemPrice() {
+ return itemPrice;
+ }
+
+ public void setItemPrice(double itemPrice) {
+ this.itemPrice = itemPrice;
+ }
+
+ public ItemType getItemType() {
+ return itemType;
+ }
+
+ public void setItemType(ItemType itemType) {
+ this.itemType = itemType;
+ }
+
+ public Date getCreatedOn() {
+ return createdOn;
+ }
+
+ public void setCreatedOn(Date createdOn) {
+ this.createdOn = createdOn;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Item item = (Item) o;
+ return id == item.id &&
+ Double.compare(item.itemPrice, itemPrice) == 0 &&
+ Objects.equals(itemName, item.itemName) &&
+ itemType == item.itemType &&
+ Objects.equals(createdOn, item.createdOn);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, itemName, itemPrice, itemType, createdOn);
+ }
+}
diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Order.java
new file mode 100644
index 0000000000..8409cacd6b
--- /dev/null
+++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Order.java
@@ -0,0 +1,44 @@
+package com.baeldung.hibernate.persistmaps.mapkey;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.MapKey;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import java.util.Map;
+
+@Entity
+@Table(name = "orders")
+public class Order {
+ @Id
+ @GeneratedValue
+ @Column(name = "id")
+ private int id;
+
+ @OneToMany(cascade = CascadeType.ALL)
+ @JoinTable(name = "order_item_mapping", joinColumns = {@JoinColumn(name = "order_id", referencedColumnName = "id")},
+ inverseJoinColumns = {@JoinColumn(name = "item_id", referencedColumnName = "id")})
+ @MapKey(name = "itemName")
+ private Map itemMap;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public Map getItemMap() {
+ return itemMap;
+ }
+
+ public void setItemMap(Map itemMap) {
+ this.itemMap = itemMap;
+ }
+}
\ No newline at end of file
diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeycolumn/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeycolumn/Order.java
new file mode 100644
index 0000000000..fa092060da
--- /dev/null
+++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeycolumn/Order.java
@@ -0,0 +1,43 @@
+package com.baeldung.hibernate.persistmaps.mapkeycolumn;
+
+import javax.persistence.CollectionTable;
+import javax.persistence.Column;
+import javax.persistence.ElementCollection;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.MapKeyColumn;
+import javax.persistence.Table;
+import java.util.Map;
+
+@Entity
+@Table(name = "orders")
+public class Order {
+ @Id
+ @GeneratedValue
+ @Column(name = "id")
+ private int id;
+
+ @ElementCollection
+ @CollectionTable(name = "order_item_mapping", joinColumns = {@JoinColumn(name = "order_id", referencedColumnName = "id")})
+ @MapKeyColumn(name = "item_name")
+ @Column(name = "price")
+ private Map itemPriceMap;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public Map getItemPriceMap() {
+ return itemPriceMap;
+ }
+
+ public void setItemPriceMap(Map itemPriceMap) {
+ this.itemPriceMap = itemPriceMap;
+ }
+}
\ No newline at end of file
diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyenumerated/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyenumerated/Order.java
new file mode 100644
index 0000000000..e1f62599b8
--- /dev/null
+++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyenumerated/Order.java
@@ -0,0 +1,48 @@
+package com.baeldung.hibernate.persistmaps.mapkeyenumerated;
+
+import com.baeldung.hibernate.persistmaps.ItemType;
+import com.baeldung.hibernate.persistmaps.mapkey.Item;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.MapKeyEnumerated;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import java.util.Map;
+
+@Entity
+@Table(name = "orders")
+public class Order {
+ @Id
+ @GeneratedValue
+ @Column(name = "id")
+ private int id;
+
+ @OneToMany(cascade = CascadeType.ALL)
+ @JoinTable(name = "order_item_mapping", joinColumns = {@JoinColumn(name = "order_id", referencedColumnName = "id")},
+ inverseJoinColumns = {@JoinColumn(name = "item_id", referencedColumnName = "id")})
+ @MapKeyEnumerated(EnumType.STRING)
+ private Map itemMap;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public Map getItemMap() {
+ return itemMap;
+ }
+
+ public void setItemMap(Map itemMap) {
+ this.itemMap = itemMap;
+ }
+}
diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Item.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Item.java
new file mode 100644
index 0000000000..97bbd5b539
--- /dev/null
+++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Item.java
@@ -0,0 +1,112 @@
+package com.baeldung.hibernate.persistmaps.mapkeyjoincolumn;
+
+import com.baeldung.hibernate.persistmaps.ItemType;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import java.util.Date;
+import java.util.Objects;
+
+@Entity
+@Table(name = "item")
+public class Item {
+ @Id
+ @GeneratedValue
+ @Column(name = "id")
+ private int id;
+
+ @Column(name = "name")
+ private String itemName;
+
+ @Column(name = "price")
+ private double itemPrice;
+
+ @Column(name = "item_type")
+ @Enumerated(EnumType.STRING)
+ private ItemType itemType;
+
+ @Temporal(TemporalType.TIMESTAMP)
+ @Column(name = "created_on")
+ private Date createdOn;
+
+ @ManyToOne(cascade = CascadeType.ALL)
+ @JoinColumn(name = "seller_id")
+ private Seller seller;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getItemName() {
+ return itemName;
+ }
+
+ public void setItemName(String itemName) {
+ this.itemName = itemName;
+ }
+
+ public double getItemPrice() {
+ return itemPrice;
+ }
+
+ public void setItemPrice(double itemPrice) {
+ this.itemPrice = itemPrice;
+ }
+
+ public ItemType getItemType() {
+ return itemType;
+ }
+
+ public void setItemType(ItemType itemType) {
+ this.itemType = itemType;
+ }
+
+ public Date getCreatedOn() {
+ return createdOn;
+ }
+
+ public void setCreatedOn(Date createdOn) {
+ this.createdOn = createdOn;
+ }
+
+ public Seller getSeller() {
+ return seller;
+ }
+
+ public void setSeller(Seller seller) {
+ this.seller = seller;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Item item = (Item) o;
+ return id == item.id &&
+ Double.compare(item.itemPrice, itemPrice) == 0 &&
+ Objects.equals(itemName, item.itemName) &&
+ itemType == item.itemType &&
+ Objects.equals(createdOn, item.createdOn) &&
+ Objects.equals(seller, item.seller);
+ }
+
+ @Override
+ public int hashCode() {
+
+ return Objects.hash(id, itemName, itemPrice, itemType, createdOn, seller);
+ }
+}
diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Order.java
new file mode 100644
index 0000000000..d680d84501
--- /dev/null
+++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Order.java
@@ -0,0 +1,44 @@
+package com.baeldung.hibernate.persistmaps.mapkeyjoincolumn;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.MapKeyJoinColumn;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import java.util.Map;
+
+@Entity
+@Table(name = "orders")
+public class Order {
+ @Id
+ @GeneratedValue
+ @Column(name = "id")
+ private int id;
+
+ @OneToMany(cascade = CascadeType.ALL)
+ @JoinTable(name = "order_item_mapping", joinColumns = {@JoinColumn(name = "order_id", referencedColumnName = "id")},
+ inverseJoinColumns = {@JoinColumn(name = "item_id", referencedColumnName = "id")})
+ @MapKeyJoinColumn(name = "seller_id")
+ private Map sellerItemMap;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public Map getSellerItemMap() {
+ return sellerItemMap;
+ }
+
+ public void setSellerItemMap(Map sellerItemMap) {
+ this.sellerItemMap = sellerItemMap;
+ }
+}
\ No newline at end of file
diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Seller.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Seller.java
new file mode 100644
index 0000000000..15b08e9fe6
--- /dev/null
+++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Seller.java
@@ -0,0 +1,51 @@
+package com.baeldung.hibernate.persistmaps.mapkeyjoincolumn;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.util.Objects;
+
+@Entity
+@Table(name = "seller")
+public class Seller {
+
+ @Id
+ @GeneratedValue
+ @Column(name = "id")
+ private int id;
+
+ @Column(name = "name")
+ private String sellerName;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getSellerName() {
+ return sellerName;
+ }
+
+ public void setSellerName(String sellerName) {
+ this.sellerName = sellerName;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Seller seller = (Seller) o;
+ return Objects.equals(sellerName, seller.sellerName);
+ }
+
+ @Override
+ public int hashCode() {
+
+ return Objects.hash(sellerName);
+ }
+}
diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeytemporal/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeytemporal/Order.java
new file mode 100644
index 0000000000..be602c1e9f
--- /dev/null
+++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeytemporal/Order.java
@@ -0,0 +1,48 @@
+package com.baeldung.hibernate.persistmaps.mapkeytemporal;
+
+import com.baeldung.hibernate.persistmaps.mapkey.Item;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.MapKeyTemporal;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import javax.persistence.TemporalType;
+import java.util.Date;
+import java.util.Map;
+
+@Entity
+@Table(name = "orders")
+public class Order {
+ @Id
+ @GeneratedValue
+ @Column(name = "id")
+ private int id;
+
+ @OneToMany(cascade = CascadeType.ALL)
+ @JoinTable(name = "order_item_mapping", joinColumns = {@JoinColumn(name = "order_id", referencedColumnName = "id")},
+ inverseJoinColumns = {@JoinColumn(name = "item_id", referencedColumnName = "id")})
+ @MapKeyTemporal(TemporalType.TIMESTAMP)
+ private Map itemMap;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public Map getItemMap() {
+ return itemMap;
+ }
+
+ public void setItemMap(Map itemMap) {
+ this.itemMap = itemMap;
+ }
+}
diff --git a/persistence-modules/hibernate-mapping/src/main/resources/logback.xml b/persistence-modules/hibernate-mapping/src/main/resources/logback.xml
new file mode 100644
index 0000000000..26beb6d5b4
--- /dev/null
+++ b/persistence-modules/hibernate-mapping/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyColumnIntegrationTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyColumnIntegrationTest.java
new file mode 100644
index 0000000000..acd77ee382
--- /dev/null
+++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyColumnIntegrationTest.java
@@ -0,0 +1,79 @@
+package com.baeldung.hibernate.persistmaps;
+
+import com.baeldung.hibernate.HibernateUtil;
+import com.baeldung.hibernate.Strategy;
+import com.baeldung.hibernate.persistmaps.mapkeycolumn.Order;
+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.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class MapKeyColumnIntegrationTest {
+ private static SessionFactory sessionFactory;
+
+ private Session session;
+
+ @BeforeClass
+ public static void beforeTests() {
+ sessionFactory = HibernateUtil.getSessionFactory(Strategy.MAP_KEY_COLUMN_BASED);
+ }
+
+ @Before
+ public void setUp() {
+ session = sessionFactory.openSession();
+ session.beginTransaction();
+ }
+
+ @Test
+ public void givenData_whenInsertUsingMapKeyColumn_thenPersistMap() {
+ Map itemPriceMap = new HashMap<>();
+ itemPriceMap.put("Wrangler Jeans", 150.0);
+ itemPriceMap.put("Lee Jeans", 180.0);
+
+
+ Order order = new Order();
+ order.setItemPriceMap(itemPriceMap);
+
+ session.persist(order);
+ session.getTransaction().commit();
+
+ assertInsertedData();
+ }
+
+ private void assertInsertedData() {
+ @SuppressWarnings("unchecked")
+ List orderList = session.createQuery("FROM Order").list();
+
+ assertNotNull(orderList);
+ assertEquals(1, orderList.size());
+
+ Order order = orderList.get(0);
+
+ Map itemPriceMap = order.getItemPriceMap();
+ assertNotNull(itemPriceMap);
+ assertEquals(itemPriceMap.size(), 2);
+ assertEquals((Double) 150.0, itemPriceMap.get("Wrangler Jeans"));
+ assertEquals((Double) 180.0, itemPriceMap.get("Lee Jeans"));
+
+ }
+
+ @After
+ public void tearDown() {
+ session.close();
+ }
+
+ @AfterClass
+ public static void afterTests() {
+ sessionFactory.close();
+ }
+}
diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyEnumeratedIntegrationTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyEnumeratedIntegrationTest.java
new file mode 100644
index 0000000000..221aa7b1d7
--- /dev/null
+++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyEnumeratedIntegrationTest.java
@@ -0,0 +1,95 @@
+package com.baeldung.hibernate.persistmaps;
+
+import com.baeldung.hibernate.HibernateUtil;
+import com.baeldung.hibernate.Strategy;
+import com.baeldung.hibernate.persistmaps.mapkey.Item;
+import com.baeldung.hibernate.persistmaps.mapkeyenumerated.Order;
+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.time.Instant;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class MapKeyEnumeratedIntegrationTest {
+ private static SessionFactory sessionFactory;
+
+ private Session session;
+
+ @BeforeClass
+ public static void beforeTests() {
+ sessionFactory = HibernateUtil.getSessionFactory(Strategy.MAP_KEY_ENUMERATED_BASED);
+ }
+
+ @Before
+ public void setUp() {
+ session = sessionFactory.openSession();
+ session.beginTransaction();
+ }
+
+ @Test
+ public void givenData_whenInsertUsingMapKeyEnumerated_thenPersistMap() {
+ Item item1 = new Item();
+ item1.setItemName("Wrangler Jeans");
+ item1.setItemPrice(150.0);
+ item1.setItemType(ItemType.JEANS);
+ item1.setCreatedOn(Date.from(Instant.ofEpochSecond(1554926573)));
+
+
+ Item item2 = new Item();
+ item2.setItemName("Armani Tshirts");
+ item2.setItemPrice(180.0);
+ item2.setItemType(ItemType.TSHIRTS);
+ item2.setCreatedOn(Date.from(Instant.ofEpochSecond(1554890573)));
+
+ Map itemMap = new HashMap<>();
+ itemMap.put(item1.getItemType(), item1);
+ itemMap.put(item2.getItemType(), item2);
+
+ Order order = new Order();
+ order.setItemMap(itemMap);
+
+ session.persist(order);
+ session.getTransaction().commit();
+
+ assertInsertedData(item1, item2);
+ }
+
+ private void assertInsertedData(Item expectedItem1, Item expectedItem2) {
+ @SuppressWarnings("unchecked")
+ List orderList = session.createQuery("FROM Order").list();
+
+ assertNotNull(orderList);
+ assertEquals(1, orderList.size());
+
+ Order order = orderList.get(0);
+
+ Map itemMap = order.getItemMap();
+ assertNotNull(itemMap);
+ assertEquals(2, itemMap.size());
+ assertEquals(expectedItem1, itemMap.get(ItemType.JEANS));
+ assertEquals(expectedItem2, itemMap.get(ItemType.TSHIRTS));
+
+ }
+
+ @After
+ public void tearDown() {
+ session.close();
+ }
+
+ @AfterClass
+ public static void afterTests() {
+ sessionFactory.close();
+ }
+}
+
diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyIntegrationTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyIntegrationTest.java
new file mode 100644
index 0000000000..b500deb78e
--- /dev/null
+++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyIntegrationTest.java
@@ -0,0 +1,95 @@
+package com.baeldung.hibernate.persistmaps;
+
+import com.baeldung.hibernate.HibernateUtil;
+import com.baeldung.hibernate.Strategy;
+import com.baeldung.hibernate.persistmaps.mapkey.Item;
+import com.baeldung.hibernate.persistmaps.mapkey.Order;
+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.time.Instant;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class MapKeyIntegrationTest {
+ private static SessionFactory sessionFactory;
+
+ private Session session;
+
+ @BeforeClass
+ public static void beforeTests() {
+ sessionFactory = HibernateUtil.getSessionFactory(Strategy.MAP_KEY_BASED);
+ }
+
+ @Before
+ public void setUp() {
+ session = sessionFactory.openSession();
+ session.beginTransaction();
+ }
+
+ @Test
+ public void givenData_whenInsertUsingMapKey_thenPersistMap() {
+ Item item1 = new Item();
+ item1.setItemName("Wrangler Jeans");
+ item1.setItemPrice(150.0);
+ item1.setItemType(ItemType.JEANS);
+ item1.setCreatedOn(Date.from(Instant.ofEpochSecond(1554926573)));
+
+
+ Item item2 = new Item();
+ item2.setItemName("Armani Tshirts");
+ item2.setItemPrice(180.0);
+ item2.setItemType(ItemType.TSHIRTS);
+ item2.setCreatedOn(Date.from(Instant.ofEpochSecond(1554890573)));
+
+ Map itemMap = new HashMap<>();
+ itemMap.put(item1.getItemName(), item1);
+ itemMap.put(item2.getItemName(), item2);
+
+ Order order = new Order();
+ order.setItemMap(itemMap);
+
+ session.persist(order);
+ session.getTransaction().commit();
+
+ assertInsertedData(item1, item2);
+ }
+
+ private void assertInsertedData(Item expectedItem1, Item expectedItem2) {
+ @SuppressWarnings("unchecked")
+ List orderList = session.createQuery("FROM Order").list();
+
+ assertNotNull(orderList);
+ assertEquals(1, orderList.size());
+
+ Order order = orderList.get(0);
+
+ Map itemMap = order.getItemMap();
+ assertNotNull(itemMap);
+ assertEquals(2, itemMap.size());
+ assertEquals(expectedItem1, itemMap.get("Wrangler Jeans"));
+ assertEquals(expectedItem2, itemMap.get("Armani Tshirts"));
+
+ }
+
+ @After
+ public void tearDown() {
+ session.close();
+ }
+
+ @AfterClass
+ public static void afterTests() {
+ sessionFactory.close();
+ }
+}
+
diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyJoinColumnIntegrationTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyJoinColumnIntegrationTest.java
new file mode 100644
index 0000000000..88b22f5c99
--- /dev/null
+++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyJoinColumnIntegrationTest.java
@@ -0,0 +1,105 @@
+package com.baeldung.hibernate.persistmaps;
+
+import com.baeldung.hibernate.HibernateUtil;
+import com.baeldung.hibernate.Strategy;
+import com.baeldung.hibernate.persistmaps.mapkeyjoincolumn.Item;
+import com.baeldung.hibernate.persistmaps.mapkeyjoincolumn.Order;
+import com.baeldung.hibernate.persistmaps.mapkeyjoincolumn.Seller;
+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.time.Instant;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class MapKeyJoinColumnIntegrationTest {
+ private static SessionFactory sessionFactory;
+
+ private Session session;
+
+ @BeforeClass
+ public static void beforeTests() {
+ sessionFactory = HibernateUtil.getSessionFactory(Strategy.MAP_KEY_JOIN_COLUMN_BASED);
+ }
+
+ @Before
+ public void setUp() {
+ session = sessionFactory.openSession();
+ session.beginTransaction();
+ }
+
+ @Test
+ public void givenData_whenInsertUsingMapKeyJoinColumn_thenPersistMap() {
+ Seller seller1 = new Seller();
+ seller1.setSellerName("Walmart");
+
+ Item item1 = new Item();
+ item1.setItemName("Wrangler Jeans");
+ item1.setItemPrice(150.0);
+ item1.setItemType(ItemType.JEANS);
+ item1.setCreatedOn(Date.from(Instant.ofEpochSecond(1554926573)));
+ item1.setSeller(seller1);
+
+
+ Seller seller2 = new Seller();
+ seller2.setSellerName("Amazon");
+
+ Item item2 = new Item();
+ item2.setItemName("Armani Tshirts");
+ item2.setItemPrice(180.0);
+ item2.setItemType(ItemType.TSHIRTS);
+ item2.setCreatedOn(Date.from(Instant.ofEpochSecond(1554890573)));
+ item2.setSeller(seller2);
+
+ Map itemSellerMap = new HashMap<>();
+ itemSellerMap.put(seller1, item1);
+ itemSellerMap.put(seller2, item2);
+
+ Order order = new Order();
+ order.setSellerItemMap(itemSellerMap);
+
+
+ session.persist(order);
+ session.getTransaction().commit();
+
+ assertInsertedData(seller1, item1, seller2, item2);
+ }
+
+ private void assertInsertedData(Seller seller1, Item expectedItem1, Seller seller2, Item expectedItem2) {
+ @SuppressWarnings("unchecked")
+ List orderList = session.createQuery("FROM Order").list();
+
+ assertNotNull(orderList);
+ assertEquals(1, orderList.size());
+
+ Order order = orderList.get(0);
+
+ Map sellerItemMap = order.getSellerItemMap();
+ assertNotNull(sellerItemMap);
+ assertEquals(2, sellerItemMap.size());
+ assertEquals(expectedItem1, sellerItemMap.get(seller1));
+ assertEquals(expectedItem2, sellerItemMap.get(seller2));
+
+ }
+
+ @After
+ public void tearDown() {
+ session.close();
+ }
+
+ @AfterClass
+ public static void afterTests() {
+ sessionFactory.close();
+ }
+}
+
diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyTemporalIntegrationTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyTemporalIntegrationTest.java
new file mode 100644
index 0000000000..7117cad22f
--- /dev/null
+++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyTemporalIntegrationTest.java
@@ -0,0 +1,96 @@
+package com.baeldung.hibernate.persistmaps;
+
+import com.baeldung.hibernate.HibernateUtil;
+import com.baeldung.hibernate.Strategy;
+import com.baeldung.hibernate.persistmaps.mapkey.Item;
+import com.baeldung.hibernate.persistmaps.mapkeytemporal.Order;
+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.time.Instant;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class MapKeyTemporalIntegrationTest {
+ private static SessionFactory sessionFactory;
+
+ private Session session;
+
+ @BeforeClass
+ public static void beforeTests() {
+ sessionFactory = HibernateUtil.getSessionFactory(Strategy.MAP_KEY_TEMPORAL_BASED);
+ }
+
+ @Before
+ public void setUp() {
+ session = sessionFactory.openSession();
+ session.beginTransaction();
+ }
+
+ @Test
+ public void givenData_whenInsertUsingMapKeyEnumerated_thenPersistMap() {
+ Date item1CreatedOn = Date.from(Instant.ofEpochSecond(1554926573));
+ Item item1 = new Item();
+ item1.setItemName("Wrangler Jeans");
+ item1.setItemPrice(150.0);
+ item1.setItemType(ItemType.JEANS);
+ item1.setCreatedOn(item1CreatedOn);
+
+
+ Date item2CreatedOn = Date.from(Instant.ofEpochSecond(1554890573));
+ Item item2 = new Item();
+ item2.setItemName("Armani Tshirts");
+ item2.setItemPrice(180.0);
+ item2.setItemType(ItemType.TSHIRTS);
+ item2.setCreatedOn(item2CreatedOn);
+
+ Map itemMap = new HashMap<>();
+ itemMap.put(item1CreatedOn, item1);
+ itemMap.put(item2CreatedOn, item2);
+
+ Order order = new Order();
+ order.setItemMap(itemMap);
+
+ session.persist(order);
+ session.getTransaction().commit();
+
+ assertInsertedData(item1CreatedOn, item1, item2CreatedOn, item2);
+ }
+
+ private void assertInsertedData(Date item1CreatedOn, Item expectedItem1, Date item2CreatedOn, Item expectedItem2) {
+ @SuppressWarnings("unchecked")
+ List orderList = session.createQuery("FROM Order").list();
+
+ assertNotNull(orderList);
+ assertEquals(1, orderList.size());
+
+ Order order = orderList.get(0);
+
+ Map itemMap = order.getItemMap();
+ assertNotNull(itemMap);
+ assertEquals(2, itemMap.size());
+ assertEquals(expectedItem1, itemMap.get(item1CreatedOn));
+ assertEquals(expectedItem2, itemMap.get(item2CreatedOn));
+
+ }
+
+ @After
+ public void tearDown() {
+ session.close();
+ }
+
+ @AfterClass
+ public static void afterTests() {
+ sessionFactory.close();
+ }
+}
diff --git a/persistence-modules/hibernate-mapping/src/test/resources/hibernate.properties b/persistence-modules/hibernate-mapping/src/test/resources/hibernate.properties
new file mode 100644
index 0000000000..c22da2496b
--- /dev/null
+++ b/persistence-modules/hibernate-mapping/src/test/resources/hibernate.properties
@@ -0,0 +1,10 @@
+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
+
diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml
index 47c733d8a7..ee55325b20 100644
--- a/persistence-modules/pom.xml
+++ b/persistence-modules/pom.xml
@@ -22,6 +22,7 @@
hbase
hibernate5
hibernate-ogm
+ hibernate-mapping
influxdb
java-cassandra
java-cockroachdb
diff --git a/pom.xml b/pom.xml
index 3bfa182d72..53ca4291bf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -967,6 +967,7 @@
libraries
persistence-modules/hibernate5
+ persistence-modules/hibernate-mapping
persistence-modules/java-jpa
persistence-modules/java-mongodb
persistence-modules/jnosql