ElementCollection таблицы коллекции Map <String, String> не создана с ключом Map как часть ключа таблицы - PullRequest
0 голосов
/ 05 сентября 2018

РЕДАКТИРОВАТЬ: проблема устранена, причина неизвестна.

Следующее сопоставление сущностей, которое содержит Map<String,String>:

public class Employee {
    @TableGenerator(name="Address_Gen",
            table="ID_GEN",
            pkColumnName="GEN_NAME",
            valueColumnName="GEN_VAL",
            pkColumnValue="Addr_Gen",
            initialValue=10000,
            allocationSize=100)
    @Id @GeneratedValue(generator="Address_Gen")    
    private int id;
    private String name;
    private long salary;

    @ElementCollection
    @CollectionTable(name="EMP_PHONE")
    @MapKeyColumn(name="PHONE_TYPE")
    @Column(name="PHONE_NUM")
    private Map<String, String> phoneNumbers;   
}

приводит к таблице сбора, которая имеет ключ (даже не описанный как первичный ключ в сгенерированном DDL), который не включает ключ карты как часть ключа:

CREATE TABLE `emp_phone` (
  `Employee_ID` int(11) DEFAULT NULL,
  `PHONE_NUM` varchar(255) DEFAULT NULL,
  `PHONE_TYPE` varchar(255) DEFAULT NULL,
  KEY `FK_EMP_PHONE_Employee_ID` (`Employee_ID`),
  CONSTRAINT `FK_EMP_PHONE_Employee_ID` FOREIGN KEY (`Employee_ID`) REFERENCES `employee` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

Это неправильно? Книга, из которой я учусь (ProJPA2), предлагает следующее:

Уникальные кортежи в таблице сбора должны быть комбинацией ключевой столбец и столбец внешнего ключа, который ссылается на источник Экземпляр сущности ... [В] итоговой таблице коллекции вместе с исходная таблица сущности EMPLOYEE, на которую она ссылается, вы можете увидеть ограничение первичного ключа для столбцов EMPLOYEE_ID и PHONE_TYPE .

Я использую фотон eclipse, eclipselink 2.5.x, mysql 8.0

Заранее спасибо.

EDIT

С тех пор я создал новый проект, используя (почти) те же аннотации, что и раньше, но теперь он генерирует ожидаемый DDL:

public class Employee {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private int id;
    private String name;
    private double salary;
    @ManyToOne  
    private Department department;

    @ElementCollection
    @CollectionTable(name="EMP_PHONE")
    @MapKeyColumn(name="PHONE_TYPE")
    @Column(name="PHONE_NUM")
    private Map<String, String> phoneNumbers = new HashMap<>();

DDL:

CREATE TABLE `emp_phone` (
  `Employee_id` int(11) NOT NULL,
  `PHONE_NUM` varchar(255) DEFAULT NULL,
  `PHONE_TYPE` varchar(255) NOT NULL,
  PRIMARY KEY (`Employee_id`,`PHONE_TYPE`),
  CONSTRAINT `FKq4updxf2ebi3swv5tf3n3jp5h` FOREIGN KEY (`Employee_id`) REFERENCES `employee` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

К сожалению, у меня нет времени на судебную экспертизу этих двух проектов, чтобы понять, что именно имело значение.

1 Ответ

0 голосов
/ 05 сентября 2018

Похоже, что в этом случае EclipseLink использует более общий подход к отображению, просто добавив столбец ключа карты в таблицу, которую он сгенерирует для типа коллекции List или Set.

Вы можете подать запрос на расширение для этого, но это не ошибка: JPA не определяет точно, как будет выглядеть сгенерированная таблица, только столбцы, используемые для полей. Предполагается, что генерация DDL помогает создавать прототипы разработки, и вы оптимизируете свою базу данных в соответствии со своим вариантом использования - добавляя индексы и т. Д. По мере необходимости, и не все базы данных работают одинаково в любом случае.

...