Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

JPA 2.0: Map Collections – Basic Type

DZone's Guide to

JPA 2.0: Map Collections – Basic Type

Learn more about JPA 2.0 map collections in this great tutorial.

· Java Zone ·
Free Resource

How do you break a Monolith into Microservices at Scale? This ebook shows strategies and techniques for building scalable and resilient microservices.

Overview

Java Persistence API (JPA) is part of Java EE implementation. JPA is a persistence framework where database relation model is abstracted and exposed as object oriented domain model. Complex relational model can be represented as objects. Object relationships are grouped to represent a business domain.
In simple terms JPA allows an application programmer to write CRUD operations without writing any SELECT, INSERT, UPDATE or DELETE statement. The Object-Relation-Mapping is converted to SQL statements. 

Map Collections

JPA 2.0 introduces Element Collection annotation to specify non- entity relationship as Basic and Embeddable type in a collection. Object relationship can be represented as java.util.Map collections. Map consists of a key and value pair.
If map value is basic or embeddable type the Element Collection annotation is used. If map value is an entity then Onetomany or ManytoOne annotation is used. The java.util.Map collections represent one side of the relationship only.
The ElementCollection annotation defines a collection of instances of a basic type or embeddable class. The ElementCollection annotation must be specified if the collection is to be mapped by means of a collection table

Mapping Strategies

The article describes development strategies to use collections mapping with basic types. JPA 2.0 uses Map for association of complex database schema. The type of mapping is determined by the value.
The Map key can be any of the following:

  1. Basic Type
  2. Embedded Object
  3. Entity

In this article we will only discuss basic type.
If map key is basic type then MapKeyColumn annotation can be used to specify the column mapping.
If map key is embeddable class the mappings for the map key columns are defaulted according to the default column mappings for the embeddable class.
If map key is entity then the MapKeyJoinColumn and MapKeyJoinColumns annotations
This article provide details on Mapping Basic Type

Setup

The code has been developed with NetBeans IDE 6.9.1 and MySQL 5.5
NetBeans provides support for JPA 2.0 implementing EclipseLink JPAProvider.
Add Eclipselink libraries to the project.
Right click on libraries. Add Library.
EclipseLink (JPA2.0)
MySQL JDBC Driver
Create a Project as Java Application
Right Click on the Project. Under New select Others , Under the categories Click on Persistence, select Persistence Unit..

The Persistence Unit as persistence.xml is created under META-INF folder. The persistence.xml has information for database connections and entity classes
persistence.xml has the following:
persistence-unit name :"javaNetPU"
provider: org.eclipse.persistence.jpa.PersistenceProvider
class: com.java.net.entity.basicEntity.CustomerBasicEntity
class: com.java.net.entity.basic.CustomerBasic
class: com.java.net.entity.basicEmbedded.CustomerBasicEmbedded
class: com.java.net.entity.basicEntity.Phone
shared-cache-mode: DISABLE_SELECTIVE
validation-mode: NONE
properties
property name="eclipselink.logging.file" value="FINEST"
property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/javanet"
property name="javax.persistence.jdbc.password" value=""
property name="javax.persistence.jdbc.user" value="root"
property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"

The following tables needs to be created Map by Basic Type

CREATE TABLE `customer` ( 
`ID` int(11) NOT NULL AUTO_INCREMENT, 
`name` varchar(45) NOT NULL, 
PRIMARY KEY (`ID`) 
)

CREATE TABLE `phone` ( 
`ID` int(11) NOT NULL AUTO_INCREMENT, 
`PhoneType` varchar(15) DEFAULT NULL, 
`PhoneNumber` varchar(15) NOT NULL, 
`customerID` int(11) DEFAULT NULL, 
`PhoneTypeID` int(11) DEFAULT NULL, 
PRIMARY KEY (`ID`), 
KEY `customerPhone_FK1` (`customerID`), 
CONSTRAINT `customerPhone_FK1` FOREIGN KEY (`customerID`) REFERENCES `customer` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION, 
)


There are three scenarios with Map where key is Basic Type.

  1. Map: Key is Basic and value is Basic
  2. Map: Key is Basic and value is Entity
  3. Map: Key is Basic and value is Embeddable

Map: Key is Basic and value is Basic

Code to demonstrate Map where both Key and value is Basic
Program Name: CusotmerBasicEntiity.java
@Entity
@Table(name = "customer")
public class CustomerBasic implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "ID")
private Integer id;
@Basic(optional = false)
@Column(name = "name")
private String name;
// The Mapping set relationship between phone and customer tables. @ElementCollection
@CollectionTable(name="phone",joinColumns=@JoinColumn(name="customerid"))
@MapKeyColumn(name="PhoneType")
@Column(name="PhoneNumber")
private Map phoneNumbers
// Getter and Setters

Program Name:PhoneTypeEnum.java
public enum PhoneTypeEnum {
Home, Mobile, Work
}

Program Name: MapBasicEnum.java
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("javaNetPU");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
// Populating the Customer object
CustomerBasic customer = new CustomerBasic();
customer.setName("Example Basic-Basic");
// Setting up Mapping relatioship
Map phoneMap = new HashMap();
phoneMap.put(PhoneTypeEnum.Home,"000-289-3214");
phoneMap.put(PhoneTypeEnum.Mobile,"001-760-2332");
customer.setPhoneNumbers(phoneMap);
em.persist(customer);
em.getTransaction().commit();
System.out.println("Persisted " );
em.close();
emf.close();
}
}

Map: Key is Basic and value is Entity

Code to demonstrate Map Key Basic and Value is Entity

Program Name: CustomerBasicEmbedded.java
public class CustomerBasicEmbedded implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "ID")
private Integer id;
@Basic(optional = false)
@Column(name = "name")
private String name;
@ElementCollection
@CollectionTable(name="phone",joinColumns=@JoinColumn(name="customerid"))
@MapKeyColumn(name="PhoneType")
private Map phoneNumbers;
// get and Setters

Program Name:PhoneEmbedded.java
// Embeddable is is non entity object
@Embeddable
public class PhoneEmbedded implements Serializable {
private static final long serialVersionUID = 1L;
@Column(name = "PhoneNumber")
private String phonenumber;
public String getPhonenumber() {
return phonenumber;
}
public void setPhonenumber(String phonenumber) {
this.phonenumber = phonenumber;
}
}

Program Name: MapBasicEmbedded.java
public class MapBasicEmbedded {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("javaNetPU");
EntityManager em = emf.createEntityManager();
// create and persist a customer
em.getTransaction().begin();
Map phoneMap = new HashMap ();
CustomerBasicEmbedded customer = new CustomerBasicEmbedded();
customer.setName("Person_BasicEmbedd_2");
PhoneEmbedded phone;
phone = new PhoneEmbedded();
phone.setPhonenumber("22200099822");
phoneMap.put("Cell", phone);
customer.setPhoneNumbers(phoneMap);
phone = new PhoneEmbedded();
phone.setPhonenumber("55876543210");
phoneMap.put("Home", phone);
customer.setPhoneNumbers(phoneMap);
em.persist(customer);
em.flush();
em.getTransaction().commit();
System.out.println("Persisted " );
em.close();
emf.close();
}
}

Map: Key is Basic and value is Embeddable

The map key is Basic and value is an Entity. Relationship is represented by OneToMany

Code to demonstrate Map Key is Basic and value is Embeddable

Program Name:CustomerBasicEntity.java
@Entity
@Table(name = "customer")
public class CustomerBasicEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "ID")
private Integer id;
@Basic(optional = false)
@Column(name = "name")
private String name;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "customer")
@MapKey(name="phoneType")
private Map phoneNumbers;
public CustomerBasicEntity() {
phoneNumbers = new HashMap();
}
// getters and setters
public Map getPhoneNumbers() {
return phoneNumbers;
}
public void addPhoneNumbers(Phone phone) {
getPhoneNumbers().put(phone.getPhoneType(),phone);
phone.setCustomer(this);
}

Program Name:Phone.java
@Entity
@Table(name = "phone")
public class Phone implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "ID")
private Integer id;
@Column(name = "PhoneNumber")
private String phoneNumber;
@Column(name = "PhoneType",insertable=true,updatable=true)
private String phoneType;
@JoinColumn(name = "customerID", referencedColumnName = "ID")
@ManyToOne(optional = false)
private CustomerBasicEntity customer;
// get and set methods

Program Name:MapBasicEntity.java
public class MapBasicEntity {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("javaNetPU");
EntityManager em = emf.createEntityManager();
// create and persist an customer
em.getTransaction().begin();
CustomerBasicEntity customerbe = new CustomerBasicEntity();
customerbe.setName("Person_4");
em.persist(customerbe);
em.flush();
Phone phone = new Phone();
phone.setCustomer(customerbe);
phone.setPhoneNumber("5555");
phone.setPhoneType("MobileEnt.");
em.persist(phone);
em.flush();
CustomerBasicEntity cbe = em.find(CustomerBasicEntity.class,customerbe.getId() );
Phone ph = em.find(Phone.class, phone.getId());
cbe.addPhoneNumbers(ph);
ph.setCustomer(cbe);
em.getTransaction().commit();
System.out.println("Persisted .... " );
em.close();
emf.close();
}

Conclusion

This article explores the Map Collections for Basic Types in detail. Map Collections and also supports Embeddable and entity as Map Key.

How do you break a Monolith into Microservices at Scale? This ebook shows strategies and techniques for building scalable and resilient microservices.

Topics:
java ,jpa 2.0

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}