显式Hibernate连接表 [英] Explicit Hibernate join table

查看:104
本文介绍了显式Hibernate连接表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个m:n关系像这里,除了有一些信息需要关联与 AuthorBook 实体。所以我想,我根本不需要 @JoinTable ,并且应该创建一个 class AuthorBook ,它包含一个到每个链接的链接作者书籍以及其他信息,对吗?

我试过它像

  @Entity 
public class AuthorBook {
@Id @ManyToOne Author author;
@Id @ManyToOne书本;
@LobOrWhatever AdditionalInformation additionalInformation;
}

我遇到了问题(我再也记不清了)。因此,我引入了一个 @GeneratedId int id ,并将引用更改为 @NaturalId 。这很有效,但有趣的是,它迫使我将附件 Author Book 传递给 Session#byNaturalId 这对我来说毫无意义(我有ID和实体应该一起获取)。我也试过

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

但是这个被拒绝告诉我author.id不是自然的id(这实际上是真的因为自然标识是作者,但其id同样适用)。



查看网页,我发现每个人都使用id而不是实体表,所以我不知道我是否尝试了一些不可能的事情......(或者愚蠢的)。 解决方案

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



我最近有类似的问题。
我发现我的解决方案是 @EmbededId



在我的数据库中有一个表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.movi​​e)
private List< Rating>评级;
}

用户:

 @Int 
@Column($ name)
@Table(name =imdb_user)

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

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

评分:

<$
@EmbityI
私人RatingId primaryKey = new RatingId($)
$ @Entity
@Table(name =rating)
public class Rating { );

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

实用工具类用于评估:

  @Embeddable 
public class RatingId implements Serializable {

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name =movie_id)
私人电影电影;
$ b @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name =imdb_user_id)
私人用户用户;
$ b $ *由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.movi​​e):ratingId.movi​​e!= 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);
返回结果;
}
}


I'm having an m:n relationsship like here, except for that there's some information be to associated with the AuthorBook entity. So I guess, I need no @JoinTable at all and should create a class AuthorBook consisting of one link to each of Author and Book and the additional information, right?

I tried it like

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

and I ran into problems (I can't recall exactly anymore). So I've introduced a @GeneratedId int id and changed the references to @NaturalId. This works mostly well, but funnily, it forces me to pass attached Author and Book to Session#byNaturalId which makes no sense to me (I have the ids and the entities should be fetched together). I also tried

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

but this was refused telling me that "author.id" is no natural id (which is actually true as the natural id is "author", but its "id" works equally well).

Looking at the web, I find everyone using ids instead of entities in such a table, so I wonder if I'm trying something impossible.... (or stupid).

解决方案

UPD: Removed unnecessary @AssociationOverrides. Added @ManyToOne(fetch = FetchType.LAZY) to avoid StackOverflowException on cascade modifications.

I had similar problem recently. I found my solution with @EmbededId.

In my database there is a table Rating that provides many-to-many relation between User and Movie, so userId and movieId are foreign keys and form a composite primary key. And this table also contains some additional information.

Here my code, I hope it will help you:

Movie:

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

User:

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

Rating:

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

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

Utility class that implements composite id for Rating:

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

这篇关于显式Hibernate连接表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆