如何映射到具有同一实体的两个字段的对象?

时间:2018-06-14 11:07:58

标签: java spring hibernate jpa

在我的Spring MVC应用程序中,我有以下User实体(为简洁而删除):

@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String email;
    private String password;
}

以下Application实体:

@Entity
public class Application {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String type;
    private String summary;
}

我想将Application实体扩展为User类型的提交者(申请人)和批准者(申请被指派批准):

@Entity
public class Application {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String type;
    private String summary;

    private User submitter;
    private User approver;
}

相应的扩展User实体:

@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String email;
    private String password;

    private Set<Application> applications;
}

Application可以有一个提交者和一个审批者,但User可以提交多个申请或等待他们的批准,所以我猜它是@OneToMany关系来自用户方。

这意味着Application方面的映射看起来像这样:

@Entity
public class Application {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String type;
    private String summary;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User submitter;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User approver;
}

但是我在关系的User方面使用了什么映射? 我想它应该是这样的:

@OneToMany(mappedBy = {"approver", "submitter"})
private Set<Application> applications;

但据我所知,用mappedBy引用多个列是不可能的。

我甚至不确定我的做法是否正确。也许我应该在User实体中为应用程序提供两个单独的字段?

我真的很感激有关如何做到这一点的任何建议。

1 个答案:

答案 0 :(得分:1)

使用当前映射,您只有一个从Application到用户的引用,即“user_id”。这意味着,目前的提交者和审批者总是相同的,我认为这不是你想要的。

在Application实体映射到的表上,您需要两个不同的列。它们需要不同的名称,并且应该与此类似地映射:

@ManyToOne
@JoinColumn(name = "user_id_submitter")
private User submitter;

@ManyToOne
@JoinColumn(name = "user_id_approver")
private User approver;

在您的用户实体上,您可以映射两个不同的@OneToMany关系,例如像这样:

@OneToMany(mappedBy = "approver")
private Set<Application> applicationsApproved;

@OneToMany(mappedBy = "submitter")
private Set<Application> applicationsSubmitted;

如果您需要组合列表,请随意提供一个结合两个列表的方法:

public Set<Application> getApplications() {
    Set<Application> allApplications = new HashSet<>();
    allApplications.addAll(applicationsSubmitted);
    allApplications.addAll(applicationsApproved);
    return allApplications;
}

(请注意:组合List当然只能以只读方式使用,不能写入数据库并更新到数据库,因为它是一个组合)

相关问题