Hibernate:HashMap <entitya,entityb =“”>注释映射</entitya,>

时间:2015-04-20 20:14:10

标签: java hibernate annotations hashmap jpa-2.0

我对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在底层数据库(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,但没有运气。我也尝试了其他可能比这个更错的东西,所以我不会在这里发布它们: - /

我也会在这里张贴期望图片,所以我更清楚地说明了这一点:

desired join table look

那么......我做错了什么?为什么我映射的HashMap不能表现得像简单的java map?起初我认为这一定是显而易见的,因为在hibernate中映射hashmap的任何人都希望map能够正常运行。但后来我发现我实际上无法在SO或其他任何地方找到答案。

提前致谢。

1 个答案:

答案 0 :(得分:0)

如果有人碰到这个或类似的问题..我最终找到了解决方案。 它实际上是在另一个SO问题中解释但我最初无法找到它。

只需要将@OneToMany更改为@ManyToMany注释: https://stackoverflow.com/a/7637117/1943765