Many-to-many mapping

This type of relationships seems like an open one, because a record from either side is related to another on the other side. Let's consider one scenario. Here, we will use the Developer and Technology classes. In this scenario, multiple developers can associate with multiple technologies and vice versa.

Getting ready

Here, we will create the tables and classes to work this demo.

Creating the tables

Use the following script to create the tables if you are not using hbm2dll=create|update:

Use the following script to create the developer table:

CREATE TABLE `developer` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
);

Use the following script to create the technology table:

CREATE TABLE `technology` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `expertise` varchar(255) DEFAULT NULL,
  `language` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
);

Use the following script to create the developer_technology table:

CREATE TABLE `developer_technology` (
  `developer_id` bigint(20) NOT NULL,
  `technology_id` bigint(20) NOT NULL,
  PRIMARY KEY (`developer_id`,`technology_id`),
  KEY `FK_TECHNOLOGY_ID` (`technology_id`),
  KEY `FK_DEVELOPER_ID` (`developer_id`),
  CONSTRAINT `FK_DEVELOPER_ID 
    FOREIGN KEY (`developer_id`) 
    REFERENCES `developer` (`id`),
  CONSTRAINT `FK_TECHNOLOGY_ID` 
    FOREIGN KEY (`technology_id`) 
    REFERENCES `technology` (`id`)
);

Creating the classes

Use the following code to create the classes:

Source file: Developer.java

@Entity
@Table(name = "developer")
public class Developer {
  @Id
  @GeneratedValue
  @Column(name = "id")
  private long id;

  @Column(name = "name")
  private String name;

  @ManyToMany(cascade = CascadeType.ALL)
  private Set<Technology> technology;

  public long getId() {
    return id;
  }

  public void setId(long id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public Set<Technology> getTechnology() {
    return technology;
  }

  public void setTechnology(Set<Technology> technology) {
    this.technology = technology;
  }

  @Override
  public String toString() {
    return "Developer" + "
 Id: " + this.id + "
 Name: " + this.name;

  }

}

Source file: Technology.java

@Entity
@Table(name = "technology")
public class Technology {

  @Id
  @GeneratedValue
  @Column(name = "id")
  private long id;

  @Column(name = "language")
  private String language;

  @Column(name = "expertise")
  private String expertise;

  @ManyToMany(mappedBy = "technology")
  private Set<Developer> developer;

  public long getId() {
    return id;
  }

  public void setId(long id) {
    this.id = id;
  }

  public String getLanguage() {
    return language;
  }

  public void setLanguage(String language) {
    this.language = language;
  }

  public String getExpertise() {
    return expertise;
  }

  public void setExpertise(String expertise) {
    this.expertise = expertise;
  }

  public Set<Developer> getDeveloper() {
    return developer;
  }

  public void setDeveloper(Set<Developer> developer) {
    this.developer = developer;
  }
  
  @Override
  public String toString() {
    return "Technology"
        +"
 Id: " + this.id
        +"
 Language: " + this.language
        +"
 Expertise: " + this.expertise;

  }

}

How to do it…

As a part of the scenario, we will create three Developer objects and two Technology objects, where all three developers have knowledge on two technologies.

Inserting a record

Here, we will insert three Developer and two Technology records in to the database. Hibernate will create a mapping between them in a third table. Execute the following code:

Code

Developer developer1= new Developer();
developer1.setName("Vishal");

Developer developer2= new Developer();
developer2.setName("Yogesh");

Developer developer3= new Developer();
developer3.setName("Virendra");

Technology technology1=new Technology();
technology1.setLanguage("Java");
technology1.setExpertise("Intermediate");

Technology technology2=new Technology();
technology2.setLanguage("Bigdata");
technology2.setExpertise("Expert");

Set<Technology> technologies= new HashSet<Technology>();
technologies.add(technology1);
technologies.add(technology2);

developer1.setTechnology(technologies);
developer2.setTechnology(technologies);
developer3.setTechnology(technologies);

Transaction transaction = session.getTransaction();
transaction.begin();
session.save(developer1);
session.save(developer2);
session.save(developer3);
transaction.commit();

Output

Hibernate: insert into developer (name) values (?)
Hibernate: insert into technology (expertise, language) values (?,?)
Hibernate: insert into technology (expertise, language) values (?,?)
Hibernate: insert into developer (name) values (?)
Hibernate: insert into developer (name) values (?)
Hibernate: insert into developer_technology (developer_id, technology_id) values (?,?)
Hibernate: insert into developer_technology (developer_id, technology_id) values (?,?)
Hibernate: insert into developer_technology (developer_id, technology_id) values (?,?)
Hibernate: insert into developer_technology (developer_id, technology_id) values (?,?)
Hibernate: insert into developer_technology (developer_id, technology_id) values (?,?)
Hibernate: insert into developer_technology (developer_id, technology_id) values (?,?)

Retrieving a record using Developer with Technology

Here, we will query the Developer object and then try to get all the Technology objects that Developer knows:

Code

Criteria criteria = session.createCriteria(Developer.class);
criteria.add(Restrictions.eq("id", 1L));

Developer developer = (Developer) criteria.uniqueResult();
System.out.println(developer.toString());

Set<Technology> tech = developer.getTechnology();
for(Technology technology : tech){
  System.out.println(technology.toString());
}

Output

Hibernate: select this_.id as id0_0_, this_.name as name0_0_ from developer this_ where this_.id=?
Developer
  Id: 1
  Name: Vishal
Hibernate: select technology0_.developer_id as developer1_0_1_, technology0_.technology_id as technology2_1_, technology1_.id as id1_0_, technology1_.expertise as expertise1_0_, technology1_.language as language1_0_ from developer_technology technology0_ inner join technology technology1_ on technology0_.technology_id=technology1_.id where technology0_.developer_id=?
Technology
  Id: 1
  Language: Java
  Expertise: Intermediate
Technology
  Id: 2
  Language: Bigdata
  Expertise: Expert

Retrieving a record using Technology with Developers

Now, we will perform a reverse process; from the Technology object, we will try to get Developers that have knowledge of that Technology. Execute the following code:

Code

Criteria criteria = session.createCriteria(Technology.class);
criteria.add(Restrictions.eq("id", 1L));

Technology technology= (Technology) criteria.uniqueResult();

System.out.println(technology);
Set<Developer> devs = technology.getDeveloper();
for(Developer developer : devs){
  System.out.println(developer.toString());
}

Output

Hibernate: select this_.id as id1_0_, this_.expertise as expertise1_0_, this_.language as language1_0_ from technology this_ where this_.id=?
Technology
  Id: 1
  Language: Java
  Expertise: Intermediate
Hibernate: select developer0_.technology_id as technology2_1_1_, developer0_.developer_id as developer1_1_, developer1_.id as id0_0_, developer1_.name as name0_0_ from developer_technology developer0_ inner join developer developer1_ on developer0_.developer_id=developer1_.id where developer0_.technology_id=?
Developer
  Id: 2
  Name: Yogesh
Developer
  Id: 3
  Name: Virendra
Developer
  Id: 1
  Name: Vishal

How it works…

From the output, we can get information on all the knowledge of technology a particular developer has and also of all the developers who have the knowledge of that particular technology. Execute the following code for their respective options:

The option from Developer:

@ManyToMany(cascade = CascadeType.ALL)
private Set<Technology> technology;

We used the @ManyToMany option; it shows that this particular developer can be associated with multiple technologies.

The option from Technology:

@ManyToMany(mappedBy="technology")
private Set<Developer> developer;

We used the @ManyToMany option; it shows that this particular technology can be associated with multiple developers. Also, mappedBy="technology" shows that this is a nonowning side.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.19.174