Interestingly, I can't find any solution for a seemingly common scenario! So I'm asking here to learn from experienced professionals in Spring Data JPA . I'll consider using Lombok to make the sample codes more concise.
Consider a simple IMDB example web application. I've defined two simple entities as below:
@Data
@Entity
public class Movie {
@Id
@GeneratedValue
private long id;
private String title;
private int year;
private int rating;
}
@Data
@Entity
public class Actor {
@Id
@GeneratedValue
private long id;
private String firstName;
private String lastName;
private Date birthday;
private String gender;
}
Now we need a join-table to link these two entities; but this is not just a simple join-table. Other than the actor
and movie
columns, this table has some additional attributes. We didn't want to waste storage by adding an ID
column here, instead we used a composite-key consisting of actor
and movie
:
@Data
@Embeddable
public class MovieActorId implements Serializable {
private Actor actor;
private Movie movie;
}
@Data
@Entity
public class MovieActor {
@EmbeddedId
private MovieActorId id;
private int salary;
private String characterName;
}
There are two Many-to-One relations here: MovieActor >-- Actor
and MovieActor >-- Movie
.
Now my main question is: "Assuming the above design, how should I define the @ManyToOne
relationships in this design?"
NOTE: I believe if we add an additional ID
column to the MovieActor
join-table instead of the composite/embedded MovieActorId
, the JPA code will become fairly straight-forward. But suppose we have some sort of limitation, and we need to stick to this design as much as possible.
You need to use @MapsId which provides the mapping for an EmbeddedId
primary key in @ManyToOne
relation
@Data
@Embeddable
public class MovieActorId implements Serializable {
private long actorId;
private long movieId;
// constructor, setter, etc
}
@Data
@Entity
public class MovieActor {
@EmbeddedId
private MovieActorId id;
@ManyToOne(cascade = CascadeType.ALL)
@MapsId("actorId")
private Actor actor;
@ManyToOne(cascade = CascadeType.ALL)
@MapsId("movieId")
private Movie movie;
...
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.