rozbicie many-to-many JPA

Mamy relację many-to-many. Rozbijamy ją na 2 one-to many. Nowa encja powinna mieć jako klucz główny parę kluczy obcych z 2 encji. Jak to zrobić?
Długo za tym googlałem - bez sukcesu. Z pomocą przyszło HibernateTools i ReverseEngenering. Oto rozwiązanie:

jedna strona asocjacji:

@Entity
public class A extends AbstractNamedEntity {

    @Id
    private Long id;
    private Collection<AB> abs;

    @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, mappedBy = "a")
    public Collection<AB> getAbs() {
        return this.abs;
    }

    public void setAbs(Collection<AB> abs {
        this.abs = abs;
    }
}

druga strona asocjacji

@Entity
public class B extends AbstractNamedEntity {

    @Id
    private Long id;
    private Collection<AB> abs ;

    @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, mappedBy = "b")
    public Collection<AB> getAbs() {
        return this.abs;
    }

    public void setAbs(Collection<AB> abs) {
        this.abs = abs;
    }

}

łącznik

@Entity
public class AB implements Serializable {

    private ABId id;
    private A a;
    private B b;

    @SuppressWarnings("unused")
    @EmbeddedId
    @AttributeOverrides( {
            @AttributeOverride(name = "aId", column = @Column(name = "a_id", unique = false, nullable = false, insertable = true, updatable = true)),
            @AttributeOverride(name = "bId", column = @Column(name = "b_id", unique = false, nullable = false, insertable = true, updatable = true)) })
    private EventGiftId getId() {
        return this.id;
    }

    public void setId(EventGiftId id) {
        this.id = id;
    }

    @ManyToOne(cascade = {}, fetch = FetchType.LAZY)
    @JoinColumn(name = "a_id", unique = false, nullable = false, insertable = false, updatable = false)
    public A getA() {
        return this.a;
    }

    public void setA(A a) {
        this.a = a;
    }

    @ManyToOne(cascade = {}, fetch = FetchType.LAZY)
    @JoinColumn(name = "b_id", unique = false, nullable = false, insertable = false, updatable = false)
    public B getB() {
        return this.b;
    }

    public void setB(B b) {
        this.b = b;
    }
}

klasa reprezentująca klucz główny łącznika

@Embeddable
public class ABId implements java.io.Serializable {

    private long aId;
    private long bId;

    // Property accessors
    @Column(name = "a_id", unique = false, nullable = false, insertable = true, updatable = true)
    public long getAId() {
        return this.aId;
    }

    public void setAId(long aId) {
        this.aid = aid;
    }

    @Column(name = "b_id", unique = false, nullable = false, insertable = true, updatable = true)
    public long getBId() {
        return this.bId;
    }

    public void setBId(long bId) {
        this.bId = bId;
    }

/* nie zapomnij o  implementacjiponiższych metod 
    public boolean equals(Object other) {
    }

    public int hashCode() {
    }
*/
}
O ile nie zaznaczono inaczej, treść tej strony objęta jest licencją Creative Commons Attribution-ShareAlike 3.0 License