Hibernate @Any, @ManyToAny and @AnyMetaDef Annotation Example

By Arvind Rai, August 28, 2016
This page will walk through hibernate @Any, @ManyToAny and @AnyMetaDef annotation example. @Any is ToOne style association and @ManyToAny is ToMany style association from an entity to any entity of several types. To distinguish an entity among several types, we need to use a discriminator value defined by @AnyMetaDef. For reusability point of view @AnyMetaDef should be used at package level. @Any associates an entity with an entity of any type which are implementing a defined interface. @ManyToAny is the collection valued form of @Any annotation. Find the complete example of @Any and @ManyToAny mapping with @AnyMetaDef annotation.

Gradle File

Find the gradle file used in our example.
build.gradle
apply plugin: 'java'
apply plugin: 'eclipse'
archivesBaseName = 'hibernate'
version = '1' 
repositories {
    mavenCentral()
}
dependencies {
    compile 'org.hibernate:hibernate-core:4.3.11.Final'
    compile 'mysql:mysql-connector-java:5.1.31'
} 

Database Table Creation using MySQL

I am using MySQL database. Find the tables used in our example.
CREATE TABLE IF NOT EXISTS `boy` (
  `id` int(11) NOT NULL,
  `age` int(11) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS `college` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS `college_students` (
  `college_id` int(11) NOT NULL,
  `student_gender` varchar(255) DEFAULT NULL,
  `student_id` int(11) NOT NULL,
  KEY `FK_s48pbsjaf21n3wuc6q1v5jvq9` (`college_id`),
  CONSTRAINT `FK_s48pbsjaf21n3wuc6q1v5jvq9` FOREIGN KEY (`college_id`) REFERENCES `college` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS `girl` (
  `id` int(11) NOT NULL,
  `age` int(11) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS `student_info` (
  `id` int(11) NOT NULL,
  `student_gender` varchar(100) DEFAULT NULL,
  `student_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;  

@AnyMetaDef Annotation Example

@AnyMetaDef is used as follows.
@AnyMetaDef(name= "StudentMetaDef", metaType = "string", idType = "int",
    metaValues = {
            @MetaValue(value = "B", targetEntity = Boy.class),
            @MetaValue(value = "G", targetEntity = Girl.class)
    }
) 
@AnyMetaDef : It provides metadata for @Any and @ManyToAny mapping. @AnyMetaDef can be used at property , class and package level. For the global reusability, hibernate recommends to use it at package level in package-info.java.
name : It is global meta definition name. This name will be used by metaDef attribute of @Any and @ManyToAny annotation.
metaType : It is the data type of value which will be inserted in the tables student_info and college_students with the mapping @Any and @ManyToAny. In our example meta type is string and values are B and G.
idType : It is the data type for the id of the table in which data will be inserted with the mapping @Any and @ManyToAny. In our case we are inserting int data type in our tables student_info and college_students.
@MetaValue : It maps a value to the target entity. metaValues attribute of @AnyMetaDef collects all defined @MetaValue.

In our example, we are using @AnyMetaDef at package level which is the recommended way.
package-info.java
@AnyMetaDef(name= "StudentMetaDef", metaType = "string", idType = "int",
    metaValues = {
            @MetaValue(value = "B", targetEntity = Boy.class),
            @MetaValue(value = "G", targetEntity = Girl.class)
    }
)
package com.concretepage.entity;
import org.hibernate.annotations.AnyMetaDef;
import org.hibernate.annotations.MetaValue; 

Hibernate XML Configuration

We need to configure our entities and package in which package-info.java resides. We are using @AnyMetaDef at package level. So the package configuration is required. It is defined as below.
<mapping package="com.concretepage.entity"/>
 
Now find the configuration file used in our example.
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">
    jdbc:mysql://localhost:3306/concretepage</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password"></property>
    <property name="hibernate.connection.pool_size">10</property>
    <property name="show_sql">true</property>
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.hbm2ddl.auto">update</property>
    <mapping class="com.concretepage.entity.Boy"/>          
    <mapping class="com.concretepage.entity.Girl"/>
    <mapping class="com.concretepage.entity.StudentInfo"/>
    <mapping class="com.concretepage.entity.College"/>
    <mapping package="com.concretepage.entity"/>
   </session-factory>
</hibernate-configuration> 

@Any Mapping Example

@Any mapping is used as follows.
@Any(
       metaDef = "StudentMetaDef",
       metaColumn = @Column(name = "student_gender")
    ) 
@Any : It defines ToOne style association of an entity to an entity of several types. Suppose we have a Student interface and two implementing classes Boy and Girl. If we want to store information of students irrespective of being girl or boy in StudentInfo, we do mapping by @Any.
metaDef : It maps the name defined by @AnyMetaDef annotation.
metaColumn : It defines the column name in which values is saved defined by @MetaValue of @AnyMetaDef annotation.

Now find the example.
StudentInfo.java
package com.concretepage.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Table;
import org.hibernate.annotations.Any;
@Entity
@Table(name="student_info")
public class StudentInfo {
	@Id
	private int id;
        @Any(
            metaDef = "StudentMetaDef",
            metaColumn = @Column(name = "student_gender")
        )
        @JoinColumn( name = "student_id" )
	private Student student;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public Student getStudent() {
		return student;
	}
	public void setStudent(Student student) {
		this.student = student;
	}
} 
Student.java
package com.concretepage.entity;
public interface Student {
    String getName();
    int getAge();
} 
Boy.java
package com.concretepage.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="boy")
public class Boy implements Student {
	@Id
	private int id;
	@Column(name="name")
	private String name;
	@Column(name="age")
	private int age;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	@Override
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
} 


Girl.java
package com.concretepage.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="girl")
public class Girl implements Student{
	@Id
	private int id;
	@Column(name="name")
	private String name;
	@Column(name="age")
	private int age;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	@Override
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
} 
HibernateUtil.java
package com.concretepage;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
    private static SessionFactory sessionFactory ;
    static {
    	   Configuration configuration = new Configuration().configure();
    	   StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().
    			applySettings(configuration.getProperties());
           sessionFactory = configuration.buildSessionFactory(builder.build());
    }
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
    public static void closeSessionFactory() {
    	sessionFactory.close();
    }
} 
HibernateAnyDemo.java
package com.concretepage;
import org.hibernate.Session;
import com.concretepage.entity.Boy;
import com.concretepage.entity.Girl;
import com.concretepage.entity.StudentInfo;
public class HibernateAnyDemo {
	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		session.beginTransaction();
		Boy boy = new Boy();
		boy.setId(1);
		boy.setName("Mukesh");
		boy.setAge(30);
		session.persist(boy);
		
		Girl girl = new Girl();
		girl.setId(1);
		girl.setName("Neerja");
		girl.setAge(25);
		session.persist(girl);
		
		StudentInfo info1 = new StudentInfo();
		info1.setId(1);
		info1.setStudent(boy);
		session.persist(info1);
		StudentInfo info2 = new StudentInfo();
		info2.setId(2);
		info2.setStudent(girl);
		session.persist(info2);
		
		session.getTransaction().commit();
		
                System.out.println("--data for id 1 --");
		StudentInfo info = (StudentInfo) session.get(StudentInfo.class, 1);
		System.out.println("Name: "+info.getStudent().getName());
		System.out.println("Age: "+info.getStudent().getAge());
		System.out.println("--data for id 2 --");
		info = (StudentInfo) session.get(StudentInfo.class, 2);
		System.out.println("Name: "+info.getStudent().getName());
		System.out.println("Age: "+info.getStudent().getAge());		

		session.close();
		HibernateUtil.closeSessionFactory();
	}
} 
Output
Hibernate: insert into boy (age, name, id) values (?, ?, ?)
Hibernate: insert into girl (age, name, id) values (?, ?, ?)
Hibernate: insert into student_info (student_gender, student_id, id) values (?, ?, ?)
Hibernate: insert into student_info (student_gender, student_id, id) values (?, ?, ?)
--data for id 1 --
Name: Mukesh
Age: 30
--data for id 2 --
Name: Neerja
Age: 25 

@ManyToAny Mapping Example

@ManyToAny mapping is used as follows.
@ManyToAny(
            metaDef = "StudentMetaDef",
            metaColumn = @Column(name = "student_gender")
          ) 

@ManyToAny : It defines ToMany style association from one entity to any entity of several types. It is collection-valued form of @Any.
metaDef : Maps the name defined by @AnyMetaDef annotation.
metaColumn : Defines the column name in which values is saved defined by @MetaValue of @AnyMetaDef annotation.

Now find the example.
College.java
package com.concretepage.entity;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.ManyToAny;
@Entity
@Table(name="college")
public class College {
	@Id
	private int id;
	@Column(name="name")
	private String name;
        @ManyToAny(
               metaDef = "StudentMetaDef",
               metaColumn = @Column(name = "student_gender")
             )
        @Cascade({org.hibernate.annotations.CascadeType.ALL})
        @JoinTable(name = "college_students",
              joinColumns = @JoinColumn(name = "college_id"),
              inverseJoinColumns = @JoinColumn(name = "student_id")
             )
        private List<Student> students = new ArrayList<>();
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public List<Student> getStudents() {
		return students;
	}
	public void setStudents(List<Student> students) {
		this.students = students;
	}
} 
HibernateManyToAnyDemo.java
package com.concretepage;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Session;
import com.concretepage.entity.Boy;
import com.concretepage.entity.College;
import com.concretepage.entity.Girl;
import com.concretepage.entity.Student;
public class HibernateManyToAnyDemo {
	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		session.beginTransaction();
		Boy boy = new Boy();
		boy.setId(1);
		boy.setName("Mukesh");
		boy.setAge(30);
		session.persist(boy);
		
		Girl girl = new Girl();
		girl.setId(1);
		girl.setName("Neerja");
		girl.setAge(25);
		session.persist(girl);
		
                College college = new College();
                college.setId(1);
                college.setName("ABCD");
                List<Student> students = new ArrayList<>();
                students.add(boy);
                students.add(girl);
                college.setStudents(students);
		session.persist(college);
		
		session.getTransaction().commit();
		
		College col = (College) session.get(College.class, 1);
		for(Student student: col.getStudents()) {
			System.out.println(student.getName()+":"+ student.getAge());
		}
		session.close();
		HibernateUtil.closeSessionFactory();
	}
} 
Output
Hibernate: insert into boy (age, name, id) values (?, ?, ?)
Hibernate: insert into girl (age, name, id) values (?, ?, ?)
Hibernate: insert into college (name, id) values (?, ?)
Hibernate: insert into college_students (college_id, student_gender, student_id) values (?, ?, ?)
Hibernate: insert into college_students (college_id, student_gender, student_id) values (?, ?, ?)
Mukesh:30
Neerja:25 
Now I am done. Happy hibernate learning!

Reference

Hibernate User Guide: @Any mapping

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE








©2024 concretepage.com | Privacy Policy | Contact Us