首页 > 解决方案 > 在 MappedSuperclass 中为 ElementCollection 使用共享表

问题描述

我有一个MappedSuperclass我也存储这样一个集合的地方:

@Data
@MappedSuperclass
public abstract class EntityMetaData {

    @Id
    @GeneratedValue
    private Long id;

    @Column(length = 150, nullable = false)
    private String runId;

    @CollectionTable
    @ElementCollection(fetch = EAGER)
    @MapKeyColumn(length = 50)
    Map<String, String> extraFields;
}

现在,正如我所期望的那样,我为每个继承的实体获得一个单独的表:

+-----------------------------+
| Tables_in_foo3              |
+-----------------------------+
| account_list                |
| account_list_extra_fields   |
| score_list                  |
| score_list_extra_fields     |
+-----------------------------+

所以我的问题是我有一种方法,我只有一个在所有实体之间共享的“extra_fields”表。

编辑 1:我尝试使用表名属性@CollectionTable(name = "extra_fields"),它确实是一个表名,而不仅仅是一个后缀。所以现在我有一个共享表,但每个实体仍然有一个 ID 列:

MariaDB [(none)]> desc foo3.extra_fields;
+------------------------+--------------+------+-----+---------+-------+
| Field                  | Type         | Null | Key | Default | Extra |
+------------------------+--------------+------+-----+---------+-------+
| score_list_id          | bigint(20)   | NO   | MUL | NULL    |       |
| a_string               | varchar(255) | YES  |     | NULL    |       |
| extra_fields_key       | datetime     | NO   | PRI | NULL    |       |
| account_list_id        | bigint(20)   | NO   | MUL | NULL    |       |
+------------------------+--------------+------+-----+---------+-------+

但是,这现在并不适用,因为我们无法在不提供所有 ID 的情况下存储一个实体。即存储分数实体被抛出异常Caused by: java.sql.SQLException: Field 'account_list_entity_id' doesn't have a default value。有没有办法让所有实体都有一个唯一 ID,并且只有一个“entity_id”作为连接键?

编辑 2:我已经添加了joinColumns=@JoinColumn(name = "id", referencedColumnName = "id") 哪个正在工作,但现在我需要所有实体的全局唯一 ID,而不仅仅是每个实体表。但是当我现在使用 UUID 时,这确实使临时查询变得困难:

@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Column(columnDefinition = "BINARY(16)")
private UUID id;

由于 id 列现在看起来像这样:

| id               |
+------------------+
| �N����E���%�_o�� | 

我可以像普通数字一样拥有更易读的 UUID 吗?或者我可以为 id 的来源(表)使用额外的列吗?

标签: hibernatespring-data-jpa

解决方案


实际上解决方案是使用继承策略JOINED。

@Data
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class EntityMetaData {

    @Id
    @GeneratedValue
    private Long id;

    @Column(length = 150, nullable = false)
    private String traceId;

    @CollectionTable(name = "unknown_fields", joinColumns=@JoinColumn(name = "id", referencedColumnName = "id"))
    @ElementCollection(fetch = EAGER)
    @MapKeyColumn(length = 50)
    Map<String, String> unknown;

}

推荐阅读