I have hibernate many-to-many mapping related question and want to understand which one is better.
I have Place and Tag tables that have a many-to-many relationship and Tag_Place table is an association table that stores the relationship between Place and Tag. Table structure is very simple, where in, Place and Tag tables have two columns each i.e., id and name. And Tag_Place table contains iid, place_id and tag_id columns.
Whenever I map these entities in Hibernate I create two entities Place and Tag that have List of each other mapped as ManyToMany. I don't need a separate class to map the association table.
Option:1Code:
@Table(name = "place")
public class Place implements Serializable {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private Long id;
private String name;
@ManyToMany(mappedBy = "places", cascade = {CascadeType.ALL})
private List<Tag> tags = new ArrayList<>();
...
}
and similarly for Tag class,
Code:
@Table(name = "tag")
public class Tag implements Serializable {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private Long id;
private String name;
@ManyToMany(cascade = {CascadeType.ALL})
private List<Place> places = new ArrayList<>();
... }
I have seen at some places where an entity is created for association table Tag_Place as well and it is mapped as OneToMany in Place and Tag entities as below. And this works too.
Option:2Code:
@Table(name = "place")
public class Place implements Serializable {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private Long id;
private String name;
@OneToMany(mappedBy = "tag", cascade = {CascadeType.ALL})
private List<TagPlace> tagPlaceList = new ArrayList<>();
...}
Tag class
Code:
@Table(name = "tag")
public class Tag implements Serializable {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private Long id;
private String name;
@OneToMany(mappedBy="place", cascade = {CascadeType.ALL})
private List<TagPlace> tagPlaceList = new ArrayList<>();
... }
and finally the `TagPlace` entity for association table
Code:
@Entity
@Table(name = "Tag_Place")
public class TagPlace implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@JoinColumn(name = "tag_id", referencedColumnName = "tag_id")
@ManyToOne
private Tag tag;
@JoinColumn(name = "place_id", referencedColumnName = "place_id")
@ManyToOne
private Player Place
..}
I have always used Option 1 but I would like to get your thoughts on which one is the preferred approach and what is the problem that we might encounter with Option 2?
Also, is there any use case where Option 2 is advisable over Option 1?