Using a shared table for ElementCollection in MappedSuperclass

时间:2018-10-02 09:18:48

标签: hibernate spring-data-jpa

I have a MappedSuperclass where I also store a collection like so:

@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;
}

Now as I would expect I get for every inherited Entity a separate table:

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

So my question is I there is a way where I only have one "extra_fields" table which is shared among all entities.

EDIT 1: I have tried to use the table name attribute @CollectionTable(name = "extra_fields") which is indeed a table name and not just a postfix. So now I have one shared table but I still have one ID column for each entity:

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    |       |
+------------------------+--------------+------+-----+---------+-------+

However this is now not woring as we can not store one Entity without providing all the ids. I.e. storing a score entity is throwng the exception Caused by: java.sql.SQLException: Field 'account_list_entity_id' doesn't have a default value. Is there a way to have one unique ID for all Entities and only one "entity_id" as join key?

EDIT 2: I have added joinColumns=@JoinColumn(name = "id", referencedColumnName = "id") which is working but now I need a global unique Id for all entities not only per entity table. But when I now use UUIDs this realy makes ad-hoc queries difficult:

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

As id columns now look like this:

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

Can I have a more readable UUID like a plain number? Or can I use an extra column for the id's origin (table)?

1 个答案:

答案 0 :(得分:0)

实际上,解决方案是使用继承策略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;

}