显式Hibernate连接表

时间:2015-09-12 22:23:20

标签: java hibernate many-to-many

我有一个m:n关系,如here,除了有一些信息要与AuthorBook实体相关联。所以我想,我根本不需要@JoinTable,应该创建一个class AuthorBook,其中包含一个指向AuthorBook的链接以及其他信息,对吗?

我尝试过像

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

我遇到了问题(我不记得了)。所以我引入了@GeneratedId int id并更改了对@NaturalId的引用。这很有效,但有趣的是,它迫使我将附件AuthorBook传递给Session#byNaturalId这对我没有意义(我有ids,实体应该一起取出) 。我也试过

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

但是这被拒绝告诉我“author.id”不是自然的id(实际上这是真的,因为自然id是“作者”,但它的“id”同样有效。)

在网上看,我发现每个人都在这样的表中使用id而不是实体,所以我想知道我是不是想尝试一些不可能的东西......(或者是愚蠢的)。

1 个答案:

答案 0 :(得分:5)

UPD:删除了不必要的@AssociationOverrides。添加了@ManyToOne(fetch = FetchType.LAZY)以避免在StackOverflowException次修改时cascade

我最近遇到过类似的问题。 我找到了@EmbededId的解决方案。

在我的数据库中有一个表Rating,它提供User和Movie之间的多对多关系,因此userId和movieId是外键并形成复合主键。此表还包含一些其他信息。

这是我的代码,我希望它会对你有所帮助:

电影:

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

用户:

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

评分:

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

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

实现评级的复合ID的实用程序类:

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