Как сохранить сущность с несколькими составными ключами - PullRequest
0 голосов
/ 26 марта 2019

Использование Hibernate 5.1.10.У меня есть компания со списком отделов и сотрудников, и я хочу разместить сотрудников в разных отделах.Вот мои сущности:

@Entity
public class Company implements Serializable {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="company_id")
    private long id;
    private String name;
    @OneToMany(mappedBy="company", cascade=CascadeType.ALL, fetch=FetchType.LAZY)
    private Set<Employee> employees;
    @OneToMany(mappedBy="company", cascade=CascadeType.ALL, fetch=FetchType.LAZY)
    private Set<Department> departments;

    ...
}

@Entity
@IdClass(EmployeeId.class)
public class Employee implements Serializable {
    public static class EmployeeId implements Serializable {
        private long id;
        private Company company;

        @Override
        public int hashCode() {...}

        @Override
        public boolean equals(Object obj) {...}
    }

    @Id
    @Column(name="employee_id")
    private long id;
    @Id
    @ManyToOne(optional=false, fetch=FetchType.LAZY)
    @JoinColumn(name="company_id", updatable=false, insertable=false)
    private Company company;
    private String name;

    ...
}

@Entity
@IdClass(DepartmendId.class)
public class Department implements Serializable {
    public static class DepartmendId implements Serializable {
        private long id;
        private Company company;

        @Override
        public int hashCode() {...}

        @Override
        public boolean equals(Object obj) {...}
    }

    @Id
    @Column(name="department_id")
    private long id;
    @Id
    @ManyToOne(optional=false, fetch=FetchType.LAZY)
    @JoinColumn(name="company_id", updatable=false, insertable=false)
    private Company company;
    private String name;

    @OneToMany(mappedBy="department", cascade=CascadeType.ALL, fetch=FetchType.LAZY)
    private Set<DepartmentEmployee> employees;

    ...
}

@Entity
@IdClass(DepartmentEmployeeId.class)
public class DepartmentEmployee implements Serializable {
    public static class DepartmentEmployeeId implements Serializable {
        private Department department;
        private Employee employee;

        @Override
        public int hashCode() {...}

        @Override
        public boolean equals(Object obj) {...}
    }

    @Id
    @ManyToOne(optional=false, fetch=FetchType.LAZY)
    @JoinColumns({
        @JoinColumn(name="department_id", updatable=false, insertable=false),
        @JoinColumn(name="company_id", updatable=false, insertable=false)
    })
    private Department department;
    @Id
    @OneToOne(optional=false, fetch=FetchType.LAZY)
    @JoinColumns({
        @JoinColumn(name="employee_id", updatable=false, insertable=false),
        @JoinColumn(name="company_id", updatable=false, insertable=false)
    })
    private Employee employee;
    private int rating;

    ...
}

Это создает следующие таблицы:

create table Company (
    company_id bigint generated by default as identity,
    name varchar(255),
    primary key (company_id)
)

create table Department (
    department_id bigint not null,
    name varchar(255),
    company_id bigint not null,
    primary key (company_id, department_id)
)

create table Employee (
    employee_id bigint not null,
    name varchar(255),
    company_id bigint not null,
    primary key (company_id, employee_id)
)

create table DepartmentEmployee (
    rating integer not null,
    employee_id bigint not null,
    company_id bigint not null,
    department_id bigint not null,
    primary key (department_id, company_id, employee_id)
)

Пока все хорошо.Я могу создать компанию с отделами и служащими и сохранить ее без каких-либо проблем.Однако, как только я пытаюсь добавить некоторых сотрудников в отдел, я получаю следующую ошибку:

26-03-2019 09:30:29 WARN  [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (main) SQL Error: 90008, SQLState: 90008
26-03-2019 09:30:29 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (main) Invalid value "5" for parameter "parameterIndex" [90008-196]

Из того, что я смог до сих пор выяснить, есть некоторая путаницав классе DepartmentEmployeeId, где hibernate считает, что есть 4 столбца ID, а не 3. Однако я не нашел никаких хороших решений.Как я могу заставить Hibernate понять, что company_id должен использоваться только один раз в IdClass?Переписать модель данных с использованием одного идентификатора на таблицу для меня не вариант.

1 Ответ

0 голосов
/ 26 марта 2019

Посмотрите на @EmbededId, используемый с @MapsId https://www.objectdb.com/api/java/jpa/MapsId

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...