编辑:问题已解决,原因不明。
以下实体映射,其中包含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
先谢谢了。
编辑
此后,我使用(几乎)与以前相同的注释创建了一个新项目,但是现在它正在生成预期的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
可悲的是,我没有时间进行两个项目的取证,以确切了解是什么与众不同。
答案 0 :(得分:1)
在这种情况下,似乎EclipseLink通过将映射键列添加到将为List或Set集合类型生成的表中,使用了一种更通用的映射方法。
您可以为此提出一个增强请求,但这不是一个错误:JPA并未完全指定生成的表的外观,仅指定了用于字段的列。假定DDL生成有助于开发原型,并且您将在用例上优化数据库-通过适当地添加索引等,并非所有数据库都能正常工作。