Home Hibernate Mapping Composite Value Types - JPA with Hibernate

Mapping Composite Value Types – JPA with Hibernate

Composition in java :

  • Let’s assume there are two java classes called College and User. Each class having common fields street, city, state, area code.
  • To increase re usability we can extract those common fields and create a new class with those fields, called ContactAddress java class.
  • Now include ContactAddress as instance variable in College and User classes.
  • We call the relationship between College and ContactAddress OR User and ContactAddress is called Composition.
  • Composition is HAS-A relation between two java objects. Following image illustrates composition in Java.
Composition in Java

Composite mapping in Hibernate :

  • Now let’s understand Database design. See following tables User and College, they have common columns names.
  • But in java to map those two table we can follow design like explained in composition.
  • What we have to understand is, ContactAddress not owning identifier (Primary Key). Here ContactAddress is composite Value Type.
  • College and User have their own identifier, they are Entity types. ContactAddress belongs to either College object or User object for each mapping.
  • In JPA terms ContactAddress is embeddable and embedded in  User and College objects.
User And College Table Structure

Note:
To understand Hibernate Entity Types and Value Types see Entity Types vs Value Types

Technologies Used in following example :

  • JPA 2.1
  • Hibernate 5.2.6
  • MySql 8.0
  • Maven 3
  • Spring Tool Suite (STS) 3.9.8
  • Java 1.8

Quick Look On JPA Annotations to understand Mapping :

@Embeddable :

  • Defines a class whose instances are stored as an intrinsic part of an owning entity and share the identity of the entity. Each of the persistent properties or fields of the embedded object is mapped to the database table for the entity. It don’t have own identifier. In this tutorial ContactAddress is Embeddable.

@Embedded :

  • Specifies a persistent field or property of an entity whose value is an instance of an embeddable class. The embeddable class must be annotated as Embeddable. In this example ContactAddress is embedded in College and User Objects.

@AttributesOverride :

  • Used to override the mapping of a Basic (whether explicit or default) property or field or Id property or field.
  • In Database tables observe the column names. User table having STREET_ADDRESS column and College table having STREET column. These two columns should map with same ContactAddress field streetAddress. @AttributeOverride gives solution for this.
  • To override multiple column names for the same field use @AtributeOverrides annotation.

Composite mapping Example:

@Embeddable
public class ContactAddress {
    
    @Column(name="STREET")
    private String streetAddress;
    
    @Column(name="STATE")
    private String state;
    
    @Column(name="CITY")
    private String city;
    
    @Column(name="ZIP_CODE")
    private String areaCode;

    // Setters and Getters
}
@Entity(name="COLLEGE")
public class College {
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
    @GenericGenerator(name = "native", strategy = "native")
    @Column(name = "COLLEGE_ID")
    private Long collegeId;
    
    @Column(name = "COLLEGE_NAME")
    private String collegeName;
    
    //will discuss about this in up coming sections(Collection Mapping)       
    @Transient
    private List emailList;
    
    @Embedded
    private ContactAddress address;

    // Setters and Getters
}
@Entity(name="USER")
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
    @GenericGenerator(name = "native", strategy = "native")
    @Column(name = "ID")
    private Long id;
    
    @Column(name="USER_NAME")
    private String userName;
    
    @Column(name="PASSWORD")
    private String password;
    
    @Temporal(value=TemporalType.TIMESTAMP)
    @Column(name="CREATED_TIME")
    private Date creationTime;
    
    @Temporal(value=TemporalType.TIMESTAMP)
    @Column(name="UPDATED_TIME")
    private Date updatedTime;
    
    @Embedded
    @AttributeOverride(name="streetAddress", [email protected](name="STREET_ADDRESS"))
    private ContactAddress address;
    
    //mapping : will discuss in collection mapping section
    @Transient
    private Collection<String> contacts;
    
    @Enumerated(value=EnumType.STRING)
    @Column(name="USER_TYPE")
    private UserType userType;

    // Setters and Getters
}

Test the mapping

- Advertisement -
public class App 
{
    public static void main( String[] args )
    {
    	EntityManagerFactory emf = null;
		EntityManager entityManager = null;
		EntityTransaction transaction = null;
		
		try{
			emf = Persistence.createEntityManagerFactory("jbd-pu");
			entityManager = emf.createEntityManager();
			transaction = entityManager.getTransaction();
			transaction.begin();
			
			College college = new College();
			college.setCollegeName("Vivekananda PG College");
			//Setting Composite Value Type
			ContactAddress address = new ContactAddress();
			address.setStreetAddress("Clock Tower, Mahbub College Campus");
			address.setCity("Secunderabad");
			address.setState("Andhrapradesh");
			address.setAreaCode("500003");
			college.setAddress(address);
			
			entityManager.persist(college);
			transaction.commit();
		}catch(Exception e){
			transaction.rollback();
		}finally{
			entityManager.close();
			emf.close();
		}
    }
}

Output :

You will see output in console like following.

Hibernate: insert into COLLEGE (ZIP_CODE, CITY, STATE, STREET, COLLEGE_NAME) values (?, ?, ?, ?, ?)
Feb 15, 2020 1:01:19 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH10001008: Cleaning up connection pool [jdbc:mysql://localhost:3306/jpa_jbd?useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&useSSL=false]

Download Application – JPA-Composite-Types1.zip (18 KB)
Download Source code – JPA-Composite-Types2.zip (13 KB)

- Advertisement -
Satish Varma
Satish Varmahttps://javabydeveloper.com
Satish is post graduated in master of computer applications and experienced software engineer with focus on Spring, JPA, REST, TDD and web development. Also founder of javabydeveloper.com. Follow him on LinkedIn or Twitter or Facebook

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Stay in Touch

Categories

Related Articles