Одностороннее сопоставление многие-ко-многим и использование только двух таблиц

У меня есть две сущности: проект, сотрудник

  • У сотрудника есть первичный ключ {employeeId} + некоторые другие атрибуты
  • У проекта есть первичный ключ {projectId}

Код:

public class Employee {
  Long employeeId;
  String name;     
}
public class Project {
  Long projectId;
  Collection<Employee> employees;
}

Сотрудник и проект - это односторонние отношения «многие ко многим». Общий подход состоит в том, чтобы иметь три таблицы: Employee, Project, EmployeesAssignedToProjects.

Employee
----------
employeeId (PK)
name

Project
----------
projectId (PK)

EmployeesAssignedToProjects
----------------------------
projectId (FK)
employeeId (FK)
{projectId,employeeId} (PK)

Поскольку у Project нет других атрибутов, кроме идентификатора, таблица Project в действительности не нужна. Это поднимает вопрос о том, как теперь сопоставить это отношение «многие ко многим», когда Project по существу сопоставляется с EmployeesAssignedToProjects.

Обратите внимание, что у Employee нет указателя на Project. Типичная конструкция mappedBy здесь не может использоваться.

[-- Обновлять --]

Проблема немного сложнее: и Project, и Employee имеют составные ключи.

  • Ключ проекта: {companyId, projectId}.
  • Ключ сотрудника: {companyId, employeeId}

Я установил 3 стола. Таблица PROJECT_EMPLOYEE имеет 3 столбца: companyId, employeeId, projectId. И я сопоставил в xml:

<many-to-many name="PROJECT" >
 <join-table name="PROJECT_EMPLOYEE">
  <join-column name="companyId" referenced-column-name="companyId"/>
  <join-column name="employeeId" referenced-column-name="employeeId" />
  <inverse-join-column name="companyId" referenced-column-name="companyId" />
  <inverse-join-column name="projectId" referenced-column-name="projectId" />
 </join-table>
</many-to-many>     

Я получил сообщение об ошибке с жалобой на то, что идентификатор компании появляется несколько раз: Повторяющийся столбец в сопоставлении для коллекции: Столбец Project.employees: companyId


person Candy Chiu    schedule 27.08.2010    source источник


Ответы (2)


Обратите внимание, что у Employee нет указателя на Project. Типичная конструкция mappedBy здесь не может использоваться.

В любом случае это не имеет значения.

И дело в том, что все отношения ManyToMany требуют JoinTable. JoinTable определяется с помощью @JoinTable явно или неявно.

@Entity
public class Project {
    @Id
    @Column(name="PROJECTID")
    private Long projectId;

    @ManyToMany
    @JoinTable(
        name="PROJECT_EMPLOYEE",
        joinColumns={@JoinColumn(name="PROJECT_PROJECTID", referencedColumnName="PROJECTID")},
        inverseJoinColumns={@JoinColumn(name="EMPLOYEE_EMPLOYEEID", referencedColumnName="EMPLOYEEID")})
    private Collection<Employee> employees;
    ...
}

Вы можете попробовать определить саму PROJECT таблицу как JoinTable, если вам нужна только поддержка чтения (и я даже не уверен, что она будет работать правильно), но этого не произойдет. работают на пишет.

Другими словами, я бы придерживался обычной конструкции для представления отношений «многие ко многим» в базе данных, то есть с таблицей соединений.

person Pascal Thivent    schedule 28.08.2010
comment
Спасибо, Паскаль, см. [Обновление]. - person Candy Chiu; 28.08.2010
comment
@Candy Пожалуйста. Но, пожалуйста, опубликуйте новый вопрос как новый. Свяжите его с этим, если хотите, но ваше обновление - это другой вопрос и проблема, даже если оно связано. Пожалуйста, не смешивайте проблемы в одном вопросе. Я не буду здесь отвечать. - person Pascal Thivent; 28.08.2010
comment
Можно ли сопоставить @JoinColumn (name = EMPLOYEE_EMPLOYEEID ..) с другим уникальным ключом в таблице сотрудников? Я не могу этого сделать. Я бы хотел, чтобы вместо целых чисел отображалось ограничение уникальности строки - person mmm; 08.08.2015

Учитывая предоставленные вами файлы классов, вы, вероятно, пытаетесь изменить отношение n - m на отношение n - 0..1.

Это можно сделать, удалив EmployeesAssignedToProjects и денормализуя таблицу Employee, добавив к ней projectId (FK):

Employee
----------
employeeId (PK)
projectId (FK)
name

Project
----------
projectId (PK)

Вы действительно этого хотите? Я не рекомендую это.

person Imre L    schedule 27.08.2010
comment
Я не хочу денормализовать таблицу сотрудников. Спасибо. - person Candy Chiu; 28.08.2010