【发布时间】:2015-06-27 17:55:29
【问题描述】:
我对 Hibernate 比较陌生,但我遇到了这个问题,可能很简单,但无论如何我都无法解决。我想映射包含 java Map 字段的实体,它应该(当然)在这个持久的 POJO 对象中表现得像 java map。为简单起见,我使实体尽可能简单,以便仍然可以识别主要问题。
所以总共有 3 个实体:
EntityA(在地图中用作键):
@Entity
@Table(name = "ENTITY_A")
public class EntityA implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
private Long id;
@Column
private String valueA;
}
EntityB(用作地图中的值):
@Entity
@Table(name = "ENTITY_B")
public class EntityB implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
private Long id;
@Column
private String valueB;
}
MainEntity(包含地图字段):
@Entity
@Table(name = "MAIN_ENTITY")
public class MainEntity implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
private Long id;
@OneToMany(fetch=FetchType.EAGER)
@JoinTable(name="ENTITYA_ENTITYB",
joinColumns=@JoinColumn(name="ENTITY_MAIN"),
inverseJoinColumns=@JoinColumn(name="ENTITY_B", unique=false),
uniqueConstraints=@UniqueConstraint(columnNames = {"ENTITY_MAIN", "ENTITY_A"}))
@MapKeyJoinColumn(name="ENTITY_A")
private Map<EntityA, EntityB> entityMap;
}
此地图的注释映射是迄今为止我找到的最佳解决方案。实际上,除了一个小细节之外,几乎所有内容都符合要求 - 以这种方式保存的地图并不像地图一样。因为当 Hibernate 在底层 DB(PostgreSQL) 中生成此连接表时,有一个有问题的约束(其中可以:entity_main 和 entity_a 组合的 1 个主键,3 个外键的另外 3 个)阻止此映射工作通常:
ALTER TABLE entitya_entityb ADD CONSTRAINT uk_5bbk6m10bx6ru2wh2gtrlpbqr UNIQUE(entity_b);
这有效地防止了该映射具有相同的对象(EntityB)作为映射值(不仅适用于一个 MainEntity 映射,而且适用于所有持久化映射)。所以我不能将相同的 EntityB 作为映射中不同键(EntityA)的值并将其持久化。我总是收到有关此约束的错误:
ERROR: duplicate key value violates unique constraint "uk_5bbk6m10bx6ru2wh2gtrlpbqr" Detail: Key (entity_b)=(3) already exists.
我已经尝试(如上所示)为 inverseJoinColumns 使用 unique=false,但没有运气。我还尝试了其他可能比这更错误的东西,所以我不会在这里发布它们:-/
我也会在这里发布期望的图片,所以我会更清楚地说明这一点:
那么..我做错了什么?为什么我映射的 HashMap 的行为不像简单的 java 映射?起初我认为这一定很明显,因为任何在休眠中映射 hashmap 的人都会期望 map 行为正确。但后来我发现我实际上无法在 SO 或其他任何地方找到我的答案。
提前致谢。
【问题讨论】:
标签: java hibernate annotations hashmap jpa-2.0