Hibernate

Bi-Directional Many to Many using user managed join table object

@Entity

@Table(name = "FOO")
public class Foo {
private UUID fooId;

@OneToMany(mappedBy = "bar")
private List<FooBar> bars;
}

@Entity
@Table(name = "BAR")
public class Bar {
private UUID barId;

@OneToMany(mappedBy = "foo")
private List<FooBar> foos;
}

@Entity
@Table(name = "FOO_BAR")
public class FooBar {
private UUID fooBarId;

@ManyToOne
@JoinColumn(name = "fooId")
private Foo foo;

@ManyToOne
@JoinColumn(name = "barId")
private Bar bar;
// You can store other objects/fields on this table here.
}

Specifies a two-way relationship between many Foo objects to many Bar objects using an intermediate join table that the user manages.

The Foo objects are stored as rows in a table called FOO. The Bar objects are stored as rows in a table called BAR. The relationships between Foo and Bar objects are stored in a table called FOO_BAR. There is a FooBar object as part of the application. 

Commonly used when you want to store extra information on the join object such as the date the relationship was created.