In the last post we saw how to define OnetoOne mapping using JPA but it was unidirectional, which means when we load Employee
we can see EmployeeAddress
but vise-versa is not true.
Today we will update our mapping so that if we fetch EmployeeAddress
we can obtain related Employee
.
Our Employee.java
will remain as it is, but we will introduce a concept of mappedBy
attribute as part of @OneToOne
in our EmployeeAddress.java
.
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). * * @return the int * @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). * * @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 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). * * @return the string * @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); } }
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.OneToOne; 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; /** The employee. */ private Employee employee = 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; } /** * Gets the employee. * * @return the employee */ @OneToOne(mappedBy="address") public Employee getEmployee() { return employee; } /** * Sets the employee. * * @param employee * the employee to set */ public void setEmployee(Employee employee) { this.employee = employee; } /** * (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); } }
To test our code we will use OneToOneUniDirectionalMainApp.java
.
OneToOneUniDirectionalMainApp.java
package com.mumz.jpa.mapping.onetoone; import javax.persistence.EntityManager; import javax.persistence.EntityTransaction; import com.mumz.jpa.JPAConnectionFactory; public class OneToOneUniDirectionalMainApp { public static void main(String[] args) { EntityManager entityManager = JPAConnectionFactory.getEntityManager("jpaPersistenceUnit"); 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(); entityManager.clear(); employee = entityManager.find(Employee.class, new Long(1)); employeeAddress = entityManager.find(EmployeeAddress.class, new Long(1)); System.out.println("Fetched Employee : " + employee); System.out.println("Employee Inside Employee Address : " + employeeAddress.getEmployee()); } catch (Exception e) { e.printStackTrace(); transaction.rollback(); } finally { entityManager.close(); } } }
N.B. If you don’t clear your EntityManager
as done in line 27 above, it will fetch result from the cache and not going to get you something from database.
And we are done, pom.xml
will remain the same as in earlier post, so is persistence.xml
.