Связать две таблицы в Hibernate

Рейтинг: -1Ответов: 1Опубликовано: 13.03.2023

есть два класса, описывающие две таблицы соответственно:

Класс Service

@Entity
@Table(name = "services")
public class Service {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    @Column
    private String srvcode;
    @Column
    private String srvname;
    
    public Service() {
        
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getSrvcode() {
        return srvcode;
    }

    public void setSrvcode(String srvcode) {
        this.srvcode = srvcode;
    }

    public String getSrvname() {
        return srvname;
    }

    public void setSrvname(String srvname) {
        this.srvname = srvname;
    }
}

Класс OtherService

@Entity
@Table(name = "other_service")
public class OtherService {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    @Column
    private String srvcode;
    @Column
    private String srvname;
    @Column
    private int type;


    public OtherService() {

    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getSrvcode() {
        return srvcode;
    }

    public void setSrvcode(String srvcode) {
        this.srvcode = srvcode;
    }

    public String getSrvname() {
        return srvname;
    }

    public void setSrvname(String srvname) {
        this.srvname = srvname;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }
}

Подскажите пожалуйста как связать эти классы (таблицы) по полям Service.srvcode = OtherService.srvcode, чтобы в итоге получить все поля из Service и поле OtherService.type?

UPDATE

Попробовала реализовать так:

Создала новый класс, который содержит поля из Service и OtherService

ServiceNew

public class ServiceNew {
    private int id;
    private String srvcode;
    private String srvname;
    private int type;
    
    public ServiceNew() {
        
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getSrvcode() {
        return srvcode;
    }

    public void setSrvcode(String srvcode) {
        this.srvcode = srvcode;
    }

    public String getSrvname() {
        return srvname;
    }

    public void setSrvname(String srvname) {
        this.srvname = srvname;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }
}

Запрос:

TypedQuery<Object[]> query = entityManager.
        createQuery("select srv.id, srv.srvname, srv.srvcode, osrv.type from Service srv join OtherService osrv on srv.srvcode = osrv.srvcode", Object[].class);

List<ServiceNew> list = new ArrayList<>();

for (Object[] results : query.getResultList()) {
    ServiceNew sNew = new ServiceNew();
    sNew.setId((int) results[0]);
    sNew.setSrvname((String) results[1]);
    sNew.setSrvcode((String) results[2]);
    sNew.setType((int) results[3]);

    list.add(sNew);
}

System.out.println(list);

Ответы

▲ 0Принят

Вашу задачу можно решить двумя способами.

Использование таблицы связей

Создайте сущность SrvCode:

@Entity
@Table(name = "srv_code")
public class SrvCode {

    @Id
    @Column("code")
    public String code;
}

И привяжите сущность Service к только что созданной сущности при помощи @JoinColumn. Для того, чтобы нельзя было создать две сущности Service, которые относятся к одному и тому же SrvCode, используйте стратегию One to One. Поставьте ограничение уникальности на колонку srvCode в таблице services.

Ваша сущность Service в итоге должна выглядеть как-то так:

@Entity
@Table(name = "services")
public class Service {

    @OneToOne
    @JoinColumn(name = "srv_code", referencedColumnName = "code")
    public SrvCode srvCode;
}

Всё то же самое выполняем для сущности OtherService:

@Entity
@Table(name = "other_services")
public class OtherService {

    @OneToOne
    @JoinColumn(name = "srv_code", referencedColumnName = "code")
    public SrvCode srvCode;
}

Сущность SrvCode:

@Entity
@Table(name = "srv_code")
public class SrvCode {

    @Id
    @Column("code")
    public String code;

    @OneToOne(mappedBy = "srvCode")
    public Service service;

    @OneToOne(mappedBy = "srvCode")
    public OtherService otherService;
}

Использование особенностей JPQL

В Spring есть возможность формировать DTO прямо в запросе. То есть вы могли бы сделать как-то вот так:

SELECT new com.example.app.dto.MyDto(s.id, os.id) 
FROM Service s
JOIN OtherService os ON os.srvCode = s.srvCode