如何在JPA中添加用户实体和好友关系实体的外键


现有用户实体,相关代码如下:


 @Entity
@Table(name = "t_users")
public class User extends Model {
    @Id
    @Column(name = "users_id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long userId;
    ...
}

以及好友关系实体,相关代码如下:


 @Entity
@Table(name = "t_relationship")
public class Relationship extends Model {
    @Id
    @Column(name = "rs_id")
    public Long relationshipId;

    @Column(name = "rs_fromuser", nullable = false)
    public User fromUser;

    @Column(name = "rs_touser", nullable = false)
    public User toUser;
    ...
}


从SQL书写来考虑,只需要在关系实体的两个Column上添加外键约束即可。但却不知道在JPA中应该怎么完成。

我个人数据库相关的知识比较欠缺,在这两个实体是不是多对多关系上存在疑问。
一个用户可以对应多个好友关系,一个好友关系对应 固定的两个用户 。应该说是n..2这种关系吗?

已经尝试使用 @ManyToMany 注解,但是我使用的Play 2框架和Ebean没有生成相对应的SQL语句。


 @Entity
@Table(name = "t_users")
public class User extends Model {
    @Id
    @Column(name = "users_id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    @ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    @JoinTable(name = "users_relationship", joinColumns = {
            @JoinColumn(name = ("user_id"), referencedColumnName = "userId"),
            @JoinColumn(name = ("rs_id"), referencedColumnName = "relationshipId")
    })
    public Long userId;
    ...
}


 @Entity
@Table(name = "t_relationship")
public class Relationship extends Model {
    @Id
    @Column(name = "rs_id")
    public Long relationshipId;

    @Column(name = "rs_fromuser", nullable = false)
    @ManyToMany(targetEntity = User.class, mappedBy = "userId")
    public User fromUser;

    @Column(name = "rs_touser", nullable = false)
    @ManyToMany(targetEntity = User.class, mappedBy = "userId")
    public User toUser;
    ...
}

生成的SQL:


 create table t_relationship (
  rs_id                     bigint auto_increment not null,
  #这里缺少了两个user id列
  rs_makedate               datetime not null,
  rs_accepted               tinyint(1) default 0 not null,
  constraint pk_t_relationship primary key (rs_id))
;

补充:

后来注意到我需要映射的是User类而非User类的集合,在这里我大概是产生了一定的误解,需要搭配Play相关的内容来检查一下。

java javaweb jpa orm java-ee

星.突变体 10 years, 5 months ago

2014.4.20再次更新

虽然上次的方法已经能够解决问题,但在开发过程中累积了一些经验后发现那样的解决方法算不上好。

下面更新下我现在的方案。


 // User model类
@Entity
@Table(name = "t_users")
public class User extends Model {
    @Id
    @Column(name = "u_id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long userId;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "fromUser")
    public List<Relationship> followUsers;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "toUser")
    public List<Relationship> followers;
    ...
}

@Entity
@Table(name = "t_relationship")
public class Relationship extends Model {
    @Id
    @Column(name = "rs_id")
    public Long relationshipId;

    @JoinColumn(name = "rs_fromuser", nullable = false, updatable = false)
    @ManyToOne(optional = false)
    public User fromUser;

    @JoinColumn(name = "rs_touser", nullable = false, updatable = false)
    @ManyToOne(optional = false)
    public User toUser;
    ...
}


以下为2014.3.18答案

问题经过探索后已经解决,但并没有完全理解其中的门道。关于JPA和ORM的基础知识不够扎实,希望能得到解惑。

就如前面所怀疑的,这并不是多对多关系,而是简单的一对一,不过是一个实体中有两个一对一关系罢了。

换用 @OneToOne 注解,并且了解了一下其他相关的内容,修改为下面的样子。


 // User model类
@Entity
@Table(name = "t_users")
public class User extends Model {
    @Id
    @Column(name = "users_id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long userId;
    ...
}

// Relationship model类
@Entity
@Table(name = "t_relationship")
public class Relationship extends Model {

    @Id
    @Column(name = "rs_id")
    public Long relationshipId;

    @JoinColumn(name = "rs_fromuser", referencedColumnName = "users_id", nullable = false, updatable=false)
    @OneToOne(optional = false, targetEntity = User.class)
    public User fromUserId;

    @JoinColumn(name = "rs_touser", referencedColumnName = "users_id", nullable = false, updatable=false)
    @OneToOne(optional = false, targetEntity = User.class)
    public User toUserId;
    ...
}

yintama answered 10 years, 5 months ago

Your Answer