2015-09-12 15 views
5

Ho una relazione m: n come here, ad eccezione del fatto che alcune informazioni devono essere associate all'entità AuthorBook. Quindi immagino, non ho bisogno di uno @JoinTable e dovrei creare uno class AuthorBook composto da un collegamento a ciascuno di Author e Book e le informazioni aggiuntive, giusto?Tabella di join di sospensione esplicita

ho provato come

@Entity 
public class AuthorBook { 
    @Id @ManyToOne Author author; 
    @Id @ManyToOne Book book; 
    @LobOrWhatever AdditionalInformation additionalInformation; 
} 

e mi sono imbattuto in problemi (non ricordo più esattamente). Quindi ho introdotto uno @GeneratedId int id e modificato i riferimenti a @NaturalId. Funziona per lo più bene, ma funnily, mi costringe a passare allegato Author e Book a Session#byNaturalId che non ha senso per me (ho gli id ​​e le entità dovrebbero essere recuperate insieme). Ho anche provato

session.byNaturalId(AuthorBook.class) 
    .using("author.id", someAuthorId) 
    .using("book.id", someBookId) 
    .load(); 

ma questo è stato rifiutato dicendomi che "author.id" non id naturale (che in realtà è vero come l'id naturale è "autore", ma la sua "id" funziona altrettanto bene).

Guardando il web, trovo che tutti usano id invece di entità in tale tabella, quindi mi chiedo se sto cercando qualcosa di impossibile .... (o stupido).

risposta

5

UPD: Rimosso inutile @AssociationOverrides. Aggiunto @ManyToOne(fetch = FetchType.LAZY) per evitare StackOverflowException su cascade modifiche.

Ho avuto un problema simile di recente. Ho trovato la mia soluzione con @EmbededId.

Nel mio database è presente una tabella Valutazione che fornisce una relazione molti a molti tra Utente e Film, quindi userId e movieId sono chiavi esterne e formano una chiave primaria composita. E questa tabella contiene anche alcune informazioni aggiuntive.

Ecco il mio codice, spero che vi aiuterà a:

Film:

@Entity 
@Table(name = "movie") 
public class Movie { 
    @Id 
    @Column(name = "movie_id") 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Integer id; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "primaryKey.movie") 
    private List<Rating> ratings; 
} 

utente:

@Entity 
@Table(name = "imdb_user") 

public class User { 
    @Id 
    @Column(name = "imdb_user_id") 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int id; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "primaryKey.user") 
    private List<Rating> ratings; 
} 

Valutazione:

@Entity 
@Table(name = "rating") 
public class Rating { 
    @EmbeddedId 
    private RatingId primaryKey = new RatingId(); 

    @Column(name = "rating_value") 
    private Integer ratingValue; 
} 

classe di utilità che implementa ID composito per R ating:

@Embeddable 
public class RatingId implements Serializable{ 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "movie_id") 
    private Movie movie; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "imdb_user_id") 
    private User user; 

    /*Generated by IDEA*/ 
    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o == null || getClass() != o.getClass()) return false; 

     RatingId ratingId = (RatingId) o; 

     if (movie != null ? !movie.equals(ratingId.movie) : ratingId.movie != null) return false; 
     return !(user != null ? !user.equals(ratingId.user) : ratingId.user != null); 

    } 

    @Override 
    public int hashCode() { 
     int result = movie != null ? movie.hashCode() : 0; 
     result = 31 * result + (user != null ? user.hashCode() : 0); 
     return result; 
    } 
} 
Problemi correlati