JPA Unidirectional One to One Mapping using MySQL

Posted on

In this tutorial we will explore how to map two entities.

Say we have two entity Employee and Address, every employee will have one associated address, association will look like:



JPA supports multiple types of mapping, in this tutorial we will see how to do “Uni-Directional” One to One Mapping.

First we will setup our pom.

pom.xml

<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">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.mumz.test.jpa</groupId>
	<artifactId>TestJPAProject</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>TestJPAProject</name>
	<description>TestJPAProject</description>
	<dependencies>
		<dependency>
			<groupId>org.hibernate.javax.persistence</groupId>
			<artifactId>hibernate-jpa-2.0-api</artifactId>
			<version>1.0.0.Final</version>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Second we will write our simple Employee entity.

Employee.java

/**
 * 
 */
package com.mumz.jpa.mapping.onetoone;

import java.io.Serializable;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

/**
 * The Class Employee.
 * 
 * @author prabhat.jha
 */
@Entity
@Table(name = "")
public class Employee implements Serializable {
	
	/** The Constant serialVersionUID. */
	private static final long	serialVersionUID	= 578658067302993111L;

	/** The id. */
	private Long				id					= null;

	/** The name. */
	private String				name				= null;

	/** The is active. */
	private String				isActive			= null;

	/** The address. */
	private EmployeeAddress		address				= null;

	/**
	 * Gets the id.
	 * 
	 * @return the id
	 */
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "EMPLOYEE_ID")
	public Long getId() {
		return id;
	}

	/**
	 * Sets the id.
	 * 
	 * @param id
	 *            the id to set
	 */
	public void setId(Long id) {
		this.id = id;
	}

	/**
	 * Gets the name.
	 * 
	 * @return the name
	 */
	@Column(name="EMPLOYEE_NAME")
	public String getName() {
		return name;
	}

	/**
	 * Sets the name.
	 * 
	 * @param name
	 *            the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * Gets the checks if is active.
	 * 
	 * @return the isActive
	 */
	@Column(name="IS_ACTIVE")
	public String getIsActive() {
		return isActive;
	}

	/**
	 * Sets the checks if is active.
	 * 
	 * @param isActive
	 *            the isActive to set
	 */
	public void setIsActive(String isActive) {
		this.isActive = isActive;
	}

	/**
	 * Gets the address.
	 * 
	 * @return the address
	 */
	@OneToOne(cascade=CascadeType.ALL)
	@JoinColumn(name="EMPLOYEE_ADDRESS_ID")
	public EmployeeAddress getAddress() {
		return address;
	}

	/**
	 * Sets the address.
	 * 
	 * @param address
	 *            the address to set
	 */
	public void setAddress(EmployeeAddress address) {
		this.address = address;
	}

	/**
	 * (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((address == null) ? 0 : address.hashCode());
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result + ((isActive == null) ? 0 : isActive.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	/**
	 * (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof Employee)) {
			return false;
		}
		Employee other = (Employee) obj;
		if (address == null) {
			if (other.address != null) {
				return false;
			}
		} else if (!address.equals(other.address)) {
			return false;
		}
		if (id == null) {
			if (other.id != null) {
				return false;
			}
		} else if (!id.equals(other.id)) {
			return false;
		}
		if (isActive == null) {
			if (other.isActive != null) {
				return false;
			}
		} else if (!isActive.equals(other.isActive)) {
			return false;
		}
		if (name == null) {
			if (other.name != null) {
				return false;
			}
		} else if (!name.equals(other.name)) {
			return false;
		}
		return true;
	}

	/** (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return String.format("Employee [id=%s, name=%s, isActive=%s, address=%s]", id, name, isActive, address);
	}
}

Third we will write the second entity EmployeeAddress.

EmployeeAddress.java

package com.mumz.jpa.mapping.onetoone;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * The Class EmployeeAddress.
 * 
 * @author prabhat.jha
 */
@Entity
@Table(name = "EMPLOYEE_ADDRESS")
public class EmployeeAddress implements Serializable {
	
	/** The Constant serialVersionUID. */
	private static final long	serialVersionUID	= -3901477366664399455L;

	/** The id. */
	private Long				id					= null;

	/** The state. */
	private String				state				= null;

	/** The city. */
	private String				city				= null;

	/**
	 * Gets the id.
	 * 
	 * @return the id
	 */
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "EMPLOYEE_ADDRESS_ID")
	public Long getId() {
		return id;
	}

	/**
	 * Sets the id.
	 * 
	 * @param id
	 *            the id to set
	 */
	public void setId(Long id) {
		this.id = id;
	}

	/**
	 * Gets the state.
	 * 
	 * @return the state
	 */
	@Column(name="EMPLOYEE_ADDRESS_STATE")
	public String getState() {
		return state;
	}

	/**
	 * Sets the state.
	 * 
	 * @param state
	 *            the state to set
	 */
	public void setState(String state) {
		this.state = state;
	}

	/**
	 * Gets the city.
	 * 
	 * @return the city
	 */
	@Column(name = "EMPLOYEE_ADDRESS_CITY")
	public String getCity() {
		return city;
	}

	/**
	 * Sets the city.
	 * 
	 * @param city
	 *            the city to set
	 */
	public void setCity(String city) {
		this.city = city;
	}

	/**
	 * (non-Javadoc).
	 * 
	 * @return the int
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((city == null) ? 0 : city.hashCode());
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result + ((getState() == null) ? 0 : getState().hashCode());
		return result;
	}

	/**
	 * (non-Javadoc).
	 * 
	 * @param obj
	 *            the obj
	 * @return true, if successful
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof EmployeeAddress)) {
			return false;
		}
		EmployeeAddress other = (EmployeeAddress) obj;
		if (city == null) {
			if (other.city != null) {
				return false;
			}
		} else if (!city.equals(other.city)) {
			return false;
		}
		if (id == null) {
			if (other.id != null) {
				return false;
			}
		} else if (!id.equals(other.id)) {
			return false;
		}
		if (getState() == null) {
			if (other.getState() != null) {
				return false;
			}
		} else if (!getState().equals(other.getState())) {
			return false;
		}
		return true;
	}

	/**
	 * (non-Javadoc).
	 * 
	 * @return the string
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return String.format("EmployeeAddress [id=%s, state=%s, city=%s]", id, getState(), city);
	}
}

Third we need persistence.xml, create persistence.xml inside your META-INF folder under src/main/resources.

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
	xmlns="http://java.sun.com/xml/ns/persistence" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation=
		"http://java.sun.com/xml/ns/persistence 
		http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
		
	<persistence-unit name="jpaPersistenceUnit"
		transaction-type="RESOURCE_LOCAL">
		<class>com.mumz.jpa.mapping.onetoone.Employee</class>
		<class>com.mumz.jpa.mapping.onetoone.EmployeeAddress</class>
		<properties>
			<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
			<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jpa_schema" />
			<property name="javax.persistence.jdbc.user" value="root" />
			<property name="javax.persistence.jdbc.password" value="root" />
		</properties>
	</persistence-unit>
</persistence>

Fourth we need the schema of the database, in this tutorial we are using MySQL.

jpa_schema


SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';

DROP SCHEMA IF EXISTS `jpa_schema` ;
CREATE SCHEMA IF NOT EXISTS `jpa_schema` DEFAULT CHARACTER SET utf8 ;
USE `jpa_schema` ;

-- -----------------------------------------------------
-- Table `jpa_schema`.`employee_address`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `jpa_schema`.`employee_address` ;

CREATE  TABLE IF NOT EXISTS `jpa_schema`.`employee_address` (
  `EMPLOYEE_ADDRESS_ID` INT(11) NOT NULL AUTO_INCREMENT ,
  `EMPLOYEE_ADDRESS_CITY` VARCHAR(45) NOT NULL ,
  `EMPLOYEE_ADDRESS_STATE` VARCHAR(45) NOT NULL ,
  PRIMARY KEY (`EMPLOYEE_ADDRESS_ID`) )
ENGINE = InnoDB
AUTO_INCREMENT = 7
DEFAULT CHARACTER SET = utf8;

-- -----------------------------------------------------
-- Table `jpa_schema`.`employee`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `jpa_schema`.`employee` ;

CREATE  TABLE IF NOT EXISTS `jpa_schema`.`employee` (
  `EMPLOYEE_ID` INT(11) NOT NULL AUTO_INCREMENT ,
  `EMPLOYEE_NAME` VARCHAR(45) NOT NULL ,
  `EMPLOYEE_ADDRESS_ID` INT(11) NOT NULL ,
  `IS_ACTIVE` VARCHAR(45) NOT NULL ,
  PRIMARY KEY (`EMPLOYEE_ID`) ,
  INDEX `FK_EMPLOYEE_ADDRESS_ID` (`EMPLOYEE_ADDRESS_ID` ASC) ,
  CONSTRAINT `FK_EMPLOYEE_ADDRESS_ID`
    FOREIGN KEY (`EMPLOYEE_ADDRESS_ID` )
    REFERENCES `jpa_schema`.`employee_address` (`EMPLOYEE_ADDRESS_ID` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB
AUTO_INCREMENT = 7
DEFAULT CHARACTER SET = utf8;

SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

Final step is write some test code to check if our code is working, Let’s write a simple Java program which will do this for us.

OneToOneUniDirectionalMainApp.java

package com.mumz.jpa.mapping.onetoone;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public class OneToOneUniDirectionalMainApp {

	public static void main(String[] args) {
		EntityManager entityManager = Persistence.createEntityManagerFactory("jpaPersistenceUnit").createEntityManager();

		Employee employee = new Employee();
		employee.setIsActive("True");
		employee.setName("Test");

		EmployeeAddress employeeAddress = new EmployeeAddress();
		employeeAddress.setCity("XYZ");
		employeeAddress.setState("ABC");
		employee.setAddress(employeeAddress);

		EntityTransaction transaction = entityManager.getTransaction();
		try {
			transaction.begin();
			entityManager.persist(employee);
			transaction.commit();
			employee = entityManager.find(Employee.class, new Long(2));
			System.out.println(employee);
		} catch (Exception e) {
			e.printStackTrace();
			transaction.rollback();
		} finally {
			entityManager.close();
		}
	}
}

Yeah we are all done!

One thought on “JPA Unidirectional One to One Mapping using MySQL

    Abhishek said:
    July 18, 2012 at 12:27 PM

    Cool dude 🙂
    Way to go

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s