Как связывать одну таблицу по нескольким связям

Есть 6 таблиц: user, landlord, tenant, house, city, contract. Связи, которые сейчас сделал на диаграмме (добавил её фото):
User связывается с landlord по ID(PK,FK).
User связывается с Tenant по ID(PK,FK).
Получается у них: это связь OnetoOne односторонний или двусторонний?

У Tenant взял ID, а у contract поле tenant Contract связывается с House по StartDate и ID
Здесь получается ManyToMany, потому что Contract является связующей таблицей.

House связывается с City по city и name
Связь OneToOne?

House связывается с landlord по id и id_landlord
OneToOne двусторонний?

В чём основной вопрос, как это должно выглядеть в программе, потому что, допустим, класс Tenant имеет несколько связей сразу, OneToOne и ManyToMany + ко всему ещё по одному и тому же ID.

Когда начал реализовывать связь, то понял, что у User появляется новый атрибут "tenant_id", хотя он по факту не нужен в этой таблице, либо же так должно быть и никуда не деться?

@Entity
@Table(name = "User", schema = "task")
public class User {

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @GeneratedValue(strategy= GenerationType.IDENTITY)
    @Column(name = "num", nullable = false)
    private Integer num;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "tenant_id")
    private Tenant tenant;

    @Column(name = "name", nullable = false)
    private String name;
    @Column(name = "email")
    private String email;
    @Column(name = "surname", nullable = false)
    private String surname;
    @Column(name = "phone", nullable = false, unique = true)
    private Integer phone;

    геттеры/сеттеры...

    public User() {
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", num=" + num +
                ", tenant=" + tenant +
                ", name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", surname='" + surname + '\'' +
                ", phone=" + phone +
                '}';
    }
}

Второй Entity выглядит вот так

@Entity
@Table(name = "Tenant", schema = "task")
public class Tenant {

@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name = "id")
private Long id;

@OneToOne(mappedBy = "tenant", cascade = {
        CascadeType.DETACH, CascadeType.REFRESH, CascadeType.MERGE,
        CascadeType.PERSIST
})
private User user;

@Column(name = "passport", unique = true)
private Boolean passport;

public Tenant(Boolean passport) {
    this.passport = passport;
}

геттеры,сеттеры...
public Tenant() {
}

@Override
public String toString() {
    return "\nTenant{" +
            "id=" + id +
            ", user=" + user +
            ", passport=" + passport +
            '}';
}
}

введите сюда описание изображения


Ответы (1 шт):

Автор решения: alex

Думаю лучше будет применить наследование.

@Entity 
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name = "USER_STATUS")
public abstract class User {}

@DiscriminatorValue("tenant")
public class Tenant extends User{}

@DiscriminatorValue("landlord")
public class Landlord extends User{}

Прочитайте про стратегии наследования Inheritance и выберите, какая вам больше подходит.

→ Ссылка