ElementCollection的地图 集合表不是使用Map键作为表键的一部分创建的

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ElementCollection的地图 集合表不是使用Map键作为表键的一部分创建的相关的知识,希望对你有一定的参考价值。

编辑:问题已解决,导致未知。

以下实体映射,其中包含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)暗示:

集合表中的唯一元组必须是键列和引用源实体实例的外键列的组合... [In]生成的集合表以及它引用的源EMPLOYEE实体表可以看到EMPLOYEE_ID和PHONE_TYPE列上的主键约束。

我正在使用eclipse photon,eclipselink 2.5.x,mysql 8.0

提前致谢。

编辑

我已经创建了一个新项目,使用(几乎)与以前相同的注释,但它现在正在生成预期的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

可悲的是,我没有时间去法医检查两个项目,看看究竟是什么造成了不同。

答案

在这种情况下,似乎EclipseLink通过将map key列添加到它将为List或Set集合类型生成的表中,使用更通用的映射方法。

您可以为此提交增强请求,但这不是错误:JPA没有准确指定生成的表的外观,只有用于字段的列。假设DDL生成是对开发原型的辅助,您可以根据用例优化数据库 - 通过适当添加索引等,并且并非所有数据库都能以相同的方式工作。

以上是关于ElementCollection的地图 集合表不是使用Map键作为表键的一部分创建的的主要内容,如果未能解决你的问题,请参考以下文章

是否可以通过 ElementCollection 查询 JPA 实体,其中 ElementCollection 包含给定元素集中的所有元素?

@OneToMany 和 @ElementCollection 之间的区别?

Hibernate - @ElementCollection - 奇怪的删除/插入行为

可嵌入和 ElementCollection 嵌套

JPA @ElementCollection 我该如何查询?

如何在休眠中为@ElementCollection 设置表名