为@ElementCollection Map更新而不是删除/插入

时间:2015-07-28 21:11:06

标签: java postgresql jpa eclipselink spring-data-jpa

我有一个定义了以下映射的实体:

@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。

1 个答案:

答案 0 :(得分:0)

您正在使用parent_id和locale作为主键,但是没有办法告诉JPA具有Embeddable:Update的信息要求构造具有唯一标识它们的内容,以便JPA可以区分它们另一个跟踪变化。 Embeddable与此完全相反,声明这些构造没有自己的标识符,因此单独使用其父ID。

您应该做的是使用parent_id,locale字段作为主键,使MyEntityTranslations成为一个实体,这样您的模型就会匹配您在数据库中设置的内容。