ManyToMany com PK
Temos um exemplo da classe Enrollment que possui uma PK (User e Offer).
Para falarmos quando um aluno que está matriculado (Classe Enrollment) terminou cada lição (Lesson), precisamos da relação ManyToMany, veja o exemplo da tabela abaixo:

Nosso código muda, o inverseJoinColumns não será como foi feito no User, visto que a classe Enrollment (matrícula), tem uma chave composta.
Dentro da classe Enrollment, temos User e Offer. Então dentro do inverseJoinColumns, abrimos uma chave adicionando dois JoinColumn's, ficando igual a tabela acima.
Classe Lesson (abstract)
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
name = "tb_lessons_done",
joinColumns = @JoinColumn(name = "lesson_id"),
inverseJoinColumns = {
@JoinColumn(name = "user_id"),
@JoinColumn(name = "offer_id")
}
)
private Set<Enrollment> enrollments = new HashSet<>();
Atualizado