2015-09-12 9 views
5

Posiadam relację m: n podobną do here, z tym że pewne informacje mają być powiązane z jednostką AuthorBook. Sądzę więc, że w ogóle nie potrzebuję @JoinTable i powinienem utworzyć class AuthorBook składający się z jednego łącza do każdego z Author i Book oraz dodatkowych informacji, prawda?Jawna tabela dołączenia hibernacji

Próbowałem go jak

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

i wpadłem na problemy (nie pamiętam dokładnie już). Wprowadziłem więc @GeneratedId int id i zmieniono odniesienia do @NaturalId. Działa to głównie dobrze, ale zabawnie, to zmusza mnie, aby przekazać dołączone Author i Book do Session#byNaturalId co nie ma dla mnie sensu (mam identyfikatory i encje powinny zostać pobrane razem). Próbowałem też

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

ale odmówiono mi powiedzieć, że „author.id” ma naturalnego id (co jest rzeczywiście prawdą, jako naturalna id to „autor”, ale jego „id” działa równie dobrze).

Patrząc na sieć, uważam, że wszyscy używają identyfikatorów zamiast podmiotów w takim stole, więc zastanawiam się, czy próbuję czegoś niemożliwego ... (lub głupiego).

Odpowiedz

5

UPD: Usunięto niepotrzebne @AssociationOverrides. Dodano @ManyToOne(fetch = FetchType.LAZY), aby uniknąć modyfikacji StackOverflowException na cascade.

Ostatnio miałem podobny problem. Znalazłem moje rozwiązanie z @EmbededId.

W mojej bazie danych znajduje się tabela Ocena, która zapewnia wiele do wielu relacji między użytkownikiem a filmem, więc userId i movieId są kluczami obcymi i tworzą złożony klucz podstawowy. Ta tabela zawiera również dodatkowe informacje.

Oto mój kod, mam nadzieję, że to pomoże:

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; 
} 

użytkownika:

@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; 
} 

Ocena:

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

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

klasy narzędzie, które wdraża złożony identyfikator dla 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; 
    } 
} 
Powiązane problemy