justanoob
justanoob

Reputation: 1807

How can i map to an object that has two fields of the same entity?

In my Spring MVC app i have the following User entity (stripped down for brevity):

@Entity
public class User {

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

And the following Application entity:

@Entity
public class Application {

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

I would like to extend the Application entity to have a submitter (the applicant) and an approver (who the application is assigned to for approval) of type 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;
}

And the corresponding extended User entity:

@Entity
public class User {

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

    private Set<Application> applications;
}

An Application can have one submitter and one approver, but a User can have multiple applications either submitted or waiting for their approval, so i guess it's a @OneToMany relationship from the user's side.

This means the mapping on the Application side would look something like this:

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

But what mapping do i use on the User side of the relationship? I suppose it should be something like this:

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

But referencing multiple columns with mappedBy is not possible as far as i know.

I'm not even sure if my approach is right. Maybe i should have two separate fields in the User entity for the applications?

I'd really appreciate any advice on how to do this.

Upvotes: 2

Views: 866

Answers (1)

Iris Hunkeler
Iris Hunkeler

Reputation: 208

With your current mapping, you have only one reference from Application to user, the "user_id". This means, that currently submitter and approver is always identical, which I think is not what you want.

On the table to which your Application entity maps, you need two different columns. They need different names and should be mapped similar to this:

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

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

On your User entity, you can then map two different @OneToMany relationships, e.g. like this:

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

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

If you need a combined list, feel free to provide a method which combines the two lists:

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

(please note: the combined List can of course only be used as read-only and cannot be written to and updated to the database, since it is a combination)

Upvotes: 1

Related Questions