我有一个定义了以下映射的实体:
@ElementCollection(fetch=FetchType.LAZY, targetClass=MyEntityTranslations.class)
@CollectionTable(name="MY_ENTITY_TRANSLATIONS", joinColumns=@JoinColumn(name="PARENT_ID"))
@MapKeyColumn(name="LOCALE")
private Map<String, MyEntityTranslations> translations;
MyEntityTranslations
类看起来像这样:
@Embeddable
public class MyEntityTranslations
{
@Column(name="NAME")
private String name;
@Column(name="DESCRIPTION")
private String description;
public MyEntityTranslations()
{
}
//getters and setters
}
MY_ENTITY_TRANSLATIONS表如下所示:
CREATE TABLE MY_ENTITY_TRANSLATIONS
(
parent_id bigint NOT NULL,
locale character varying NOT NULL,
name character varying,
description character varying,
CONSTRAINT my_entity_translations_pkey PRIMARY KEY (parent_id, locale)
);
一切正常并且符合预期,但是当我更新MyEntityTranslations
中的名称或描述时,它正在执行DELETE,后跟INSERT而不仅仅是UPDATE。
我想可能会向equals()
添加hashCode()
和MyEntityTranslations
方法,这样JPA就可以知道它是否应该只是更新。但是,我很快意识到我没有MyEntityTranslations
中所需的信息来正确覆盖这些方法。
在浏览了这个问题之后,我发现List
存在很多解决此问题的地方,解决方案是添加@OrderColumn
注释或将其更改为Set
。但是,我找不到Map
的任何内容。
实际上,在将记录插入MY_ENTITY_TRANSLATIONS表之后,除非删除id等于PARENT_ID列的实体,否则永远不需要删除它。有什么我可以使用实体或embeddable来允许JPA总是执行UPDATE而不是DELETE / INSERT行为吗?
如果它有所作为,我正在使用PostgreSQL,Spring Data JPA和EclipseLink。
答案 0 :(得分:0)
您正在使用parent_id和locale作为主键,但是没有办法告诉JPA具有Embeddable:Update的信息要求构造具有唯一标识它们的内容,以便JPA可以区分它们另一个跟踪变化。 Embeddable与此完全相反,声明这些构造没有自己的标识符,因此单独使用其父ID。
您应该做的是使用parent_id,locale字段作为主键,使MyEntityTranslations成为一个实体,这样您的模型就会匹配您在数据库中设置的内容。