JPA Override Attribute with MySQL

Posted on Updated on

Use Case: Override attributes defined in another entity.


We want to specify column mapping the main entity and not in the embeddable entity or you can mix and match both.

We will follow the similar domain model as we followed in JPA, Hibernate Composite Embeddable Primary Key, so you can take the schema

First we need our main entity class which is Student.java.

Student.java

package com.mumz.jpa.embeddable.overrideattributes;

import java.io.Serializable;

import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * The Class StudentOverrideAttributes.
 */
@Entity
@Table(name="STUDENT")
public class StudentOverrideAttributes implements Serializable{
	
	/** The Constant serialVersionUID. */
	private static final long	serialVersionUID	= 7302926659309751104L;
	
	/** The id. */
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Column(name="student_id")
	private Integer id = null;
	
	/** The address. */
	@Embedded
	@AttributeOverrides({
		@AttributeOverride(name="street", column=@Column(name="street"))
	})
	private AddressOverrideAttributes address = null;
	
	/** The name. */
	private String name= null;
	
	/**
	 * Gets the id.
	 * 
	 * @return the id
	 */
	public Integer getId() {
		return id;
	}
	
	/**
	 * Sets the id.
	 * 
	 * @param id
	 *            the id to set
	 */
	public void setId(Integer id) {
		this.id = id;
	}
	
	/**
	 * Gets the address.
	 * 
	 * @return the address
	 */
	public AddressOverrideAttributes getAddress() {
		return address;
	}
	
	/**
	 * Sets the address.
	 * 
	 * @param address
	 *            the address to set
	 */
	public void setAddress(AddressOverrideAttributes address) {
		this.address = address;
	}
	
	/**
	 * Gets the name.
	 * 
	 * @return the name
	 */
	@Access(AccessType.PROPERTY)
	@Column(name="student_name")
	public String getName() {
		return name;
	}
	
	/**
	 * Sets the name.
	 * 
	 * @param name
	 *            the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}
	
	/** (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 + ((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 StudentOverrideAttributes)) {
			return false;
		}
		StudentOverrideAttributes other = (StudentOverrideAttributes) 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 (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("StudentOverrideAttributes [id=%s, address=%s, name=%s]", id, address, name);
	}
}

The class is a simple entity class, important thing to note is the usage of @AttributeOverrides, In the embeddable class AddressOverrideAttributes (code below), we haven’t specified column for field street.

Second we will write our embeddable class and we won’t specify column mapping for street

AddressOverrideAttributes.java

package com.mumz.jpa.embeddable.overrideattributes;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Embeddable;

/**
 * The Class AddressOverrideAttributes.
 */
@Embeddable
public class AddressOverrideAttributes implements Serializable{
	
	/** The Constant serialVersionUID. */
	private static final long	serialVersionUID	= -3300286178321717276L;
	
	/** The street. */
	private String street = null;
	
	/** The city. */
	@Column(name="city")
	private String city = null;
	
	/** The state. */
	@Column(name="state")
	private String state = null;
	
	/** The zip code. */
	@Column(name="zipCode")
	private String zipCode = null;
	
	/**
	 * Gets the street.
	 * 
	 * @return the street
	 */
	public String getStreet() {
		return street;
	}
	
	/**
	 * Sets the street.
	 * 
	 * @param street
	 *            the new street
	 */
	public void setStreet(String street) {
		this.street = street;
	}
	
	/**
	 * Gets the city.
	 * 
	 * @return the city
	 */
	public String getCity() {
		return city;
	}
	
	/**
	 * Sets the city.
	 * 
	 * @param city
	 *            the new city
	 */
	public void setCity(String city) {
		this.city = city;
	}
	
	/**
	 * Gets the state.
	 * 
	 * @return the state
	 */
	public String getState() {
		return state;
	}
	
	/**
	 * Sets the state.
	 * 
	 * @param state
	 *            the new state
	 */
	public void setState(String state) {
		this.state = state;
	}
	
	/**
	 * Gets the zip code.
	 * 
	 * @return the zip code
	 */
	public String getZipCode() {
		return zipCode;
	}
	
	/**
	 * Sets the zip code.
	 * 
	 * @param zipCode
	 *            the new zip code
	 */
	public void setZipCode(String zipCode) {
		this.zipCode = zipCode;
	}
	
	/** (non-Javadoc)
	 * @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 + ((state == null) ? 0 : state.hashCode());
		result = prime * result + ((street == null) ? 0 : street.hashCode());
		result = prime * result + ((zipCode == null) ? 0 : zipCode.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 AddressOverrideAttributes)) {
			return false;
		}
		AddressOverrideAttributes other = (AddressOverrideAttributes) obj;
		if (city == null) {
			if (other.city != null) {
				return false;
			}
		} else if (!city.equals(other.city)) {
			return false;
		}
		if (state == null) {
			if (other.state != null) {
				return false;
			}
		} else if (!state.equals(other.state)) {
			return false;
		}
		if (street == null) {
			if (other.street != null) {
				return false;
			}
		} else if (!street.equals(other.street)) {
			return false;
		}
		if (zipCode == null) {
			if (other.zipCode != null) {
				return false;
			}
		} else if (!zipCode.equals(other.zipCode)) {
			return false;
		}
		return true;
	}
	
	/** (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return String.format("AddressOverrideAttributes [street=%s, city=%s, state=%s, zipCode=%s]", street, city, state, zipCode);
	}
}

Third JPA needs persistence.xml where we specify the entity classes and connection details.

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="myJPAService" transaction-type="RESOURCE_LOCAL">
		<class>com.mumz.jpa.embeddable.overrideattributes.AddressOverrideAttributes</class>
		<class>com.mumz.jpa.embeddable.overrideattributes.StudentOverrideAttributes</class>
		<properties>
			<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
			<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/test"/>
			<property name="javax.persistence.jdbc.user" value="root"/>
			<property name="javax.persistence.jdbc.password" value="root"/>
		</properties>
	</persistence-unit>
</persistence>

Fourth let’s write our test class TestEmbeddableMainApp.java.

TestEmbeddableMainApp.java

package com.mumz.jpa.embeddable.overrideattributes;

import javax.persistence.EntityManager;

import com.mumz.jpa.JPAConnectionFactory;

public class TestEmbeddableMainApp {

	/**
	 * @param args
	 */
	static void saveStudent() {
		EntityManager em = JPAConnectionFactory.getEntityManager();
		try {
			AddressOverrideAttributes address = new AddressOverrideAttributes();
			address.setCity("ZZZZZZ");
			address.setState("YYYYYYYY");
			address.setStreet("XXXXXXXX");
			address.setZipCode("111111");
			StudentOverrideAttributes student = new StudentOverrideAttributes();
			student.setAddress(address);
			student.setName("AAAAAAA");
			em.getTransaction().begin();
			student = em.merge(student);
			em.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			em.close();
		}

	}

	public static void main(String[] args) {
		saveStudent();
	}
}

A unility class JPAConnectionFactory.java which creates EntityManager using the configuration provided in persistence.xml

JPAConnectionFactory.java

package com.mumz.jpa;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

/**
 * A factory for creating JPAConnection objects.
 */
public class JPAConnectionFactory {
	
	/**
	 * Gets the entity manager.
	 * 
	 * @return the entity manager
	 */
	public static EntityManager getEntityManager(){
		EntityManagerFactory emf = Persistence.createEntityManagerFactory("myJPAService");
		return emf.createEntityManager();
	}
}

Database schema

delimiter $$

CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 */$$

CREATE TABLE `student` (
  `ID` bigint(20) NOT NULL AUTO_INCREMENT,
  `STUDENT_NAME` varchar(45) DEFAULT NULL,
  `STREET` varchar(45) DEFAULT NULL,
  `CITY` varchar(45) DEFAULT NULL,
  `STATE` varchar(45) DEFAULT NULL,
  `ZIPCODE` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8$$

That’s all for overriding attributes.

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