Here, we will create a different scenario for a better understanding of the relationship. We will take a look at the use of both one-to-many and many-to-one relationships in a single example.
Now, we will create a relationship between actor and movie tables, where one actor is associated with one movie, but one movie can be associated with multiple actors.
We will create the classes and tables for Movie
and Actor
.
Use the following script to create the tables if you are not using hbm2dll=create|update
:
Use the following script to create the movie
table:
CREATE TABLE `movie` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) )
Use the following script to create the actor
table:
CREATE TABLE `actor` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `actorname` varchar(255) DEFAULT NULL, `movie_id` bigint(20) DEFAULT NULL, PRIMARY KEY (`id`), KEY `FK_MOVIE_ID` (`movie_id`), CONSTRAINT `FK_MOVIE_ID` FOREIGN KEY (`movie_id`) REFERENCES `movie` (`id`) )
Use the following code to create the classes:
Source file: Movie.java
@Entity @Table(name = "movie") public class Movie { @Id @GeneratedValue @Column(name = "id") private long id; @Column(name = "name") private String name; @OneToMany(mappedBy = "movie") private Set<Actor> actors; 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<Actor> getActors() { return actors; } public void setActors(Set<Actor> actors) { this.actors = actors; } @Override public String toString() { return "Movie" + " Id: " + this.id + " Name: " + this.name; } }
@Entity @Table(name = "actor") public class Actor { @Id @GeneratedValue @Column(name = "id") private long id; @Column(name = "actorname") private String actorName; @ManyToOne @JoinColumn(name = "movie_id") private Movie movie; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getActorName() { return actorName; } public void setActorName(String actorName) { this.actorName = actorName; } public Movie getMovie() { return movie; } public void setMovie(Movie movie) { this.movie = movie; } @Override public String toString() { return "Actor" + " Id: " + this.id + " Name: " + this.actorName; } }
In this section, we will see how to achieve one-to-many or many-to-one associativity using Actor and Movie classes. Also we will learn how to retrieve data from either side i.e. retrieve movie from actor
and actor from movie
.
Use the following code to insert a record, and you will understand how this relationship works:
Movie movie= new Movie(); movie.setName("Furious 7"); Actor actor1 = new Actor(); actor1.setActorName("Vin Diesel"); actor1.setMovie(movie); Actor actor2= new Actor(); actor2.setActorName("Paul Walker"); actor2.setMovie(movie); Transaction transaction = session.getTransaction(); transaction.begin(); session.save(movie); session.save(actor1); session.save(actor2); transaction.commit();
Here, we will retrieve the Actor
object and also the Movie
object associated with it:
Criteria criteria = session.createCriteria(Actor.class); criteria.add(Restrictions.eq("actorName", "Paul Walker")); Actor actor = (Actor) criteria.uniqueResult(); System.out.println(actor); System.out.println(actor.getMovie());
Hibernate: select this_.id as id1_1_, this_.actorname as actorname1_1_,this_.movie_id as movie3_1_1_, movie2_.id as id0_0_, movie2_.name as name0_0_ from actor this_ left outer join movie movie2_ on this_.movie_id=movie2_.id where this_.actorname=? Actor Id: 2 Name: Paul Walker Movie Id: 1 Name: Furious 7
Now, we will retrieve the Movie
object and get the Actor
object associated with that movie:
Criteria criteria = session.createCriteria(Movie.class); criteria.add(Restrictions.eq("id", 1L)); Movie movie = (Movie) criteria.uniqueResult(); System.out.println(movie); Set<Actor> actors = movie.getActors(); for(Actor actor : actors){ System.out.println(actor); }
Hibernate: select this_.id as id0_0_, this_.name as name0_0_ from movie this_ where this_.id=? Movie Id: 1 Name: Furious 7 Hibernate: select actors0_.movie_id as movie3_0_1_, actors0_.id as id1_, actors0_.id as id1_0_, actors0_.actorname as actorname1_0_, actors0_.movie_id as movie3_1_0_ from actor actors0_ where actors0_.movie_id=? Actor Id: 1 Name: Vin Diesel Actor Id: 2 Name: Paul Walker
From the output, we can easily understand how this relationship works. Let's take a look at an option used in the previous example.
The option from the Movie
class:
@ManyToOne @JoinColumn(name="movie_id") private Movie movie;
In the preceding code, we used the @ManyToOne
annotation; it shows many actors associated with one movie. This side of the relationship is considered to be the owning side and is responsible for the update if we use bidirectional operations.
The option from the Actor
class:
@OneToMany(mappedBy = "movie") private Set<Actor> actors;
In the preceding code, we used mappedBy = "movie"
with the @OneToMany
annotation; @OneToMany
shows that one movie is associated with multiple actors, mappedBy = "movie"
shows that this is the nonowning side of the relationship, and you can get the parent object from the mappedBy
movie entity.