Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define MapKey column name on Map<String, Embeddable>

Short version:
I'm trying to create an:

@ElementCollection
private Map<String, Item> items;

, where Item is @Embeddable, and be able to define the column name created in Item table for the map's key. Hibernate version: 5.0.12.Final

Full explanation:
Following is a simplified example that reproduces my problem. My starting point is a List of @Embeddable.

@Entity
public class Root {
    @Id
    private Long code;   

    private String value;    

    @ElementCollection
    private Set<Item> items;
}
@Embeddable
public class Item {
    private String keyValue;    
    private String otherValue;
}

with this mappings hibernate creates the following tables:

create table root (
    code int8 not null,
    value varchar(255),
    primary key (code)
);

create table root_items (
    root_code int8 not null,
    key_value varchar(255),
    other_value varchar(255)
);

alter table root_items 
    add constraint FK1o7au7f9ccr8144vyfgsr194v 
    foreign key (root_code) 
    references root;

So far so good. Next, I'm trying to convert the List to a Map and use Item.keyValue as the map's key:

@Entity
public class Root {
    @Id
    private Long code;

    private String value;

    @ElementCollection
    private Map<String, Item> items;
}
@Embeddable
public class Item {
    private String otherValue;
}

It works, but in root_items table the map's key column is always called items_key and I'm unable to find how to force this name to key_value.

I've tried the following alternatives:

@ElementCollection
@MapKeyJoinColumn(name = "keyValue")
private Map<String, Item> items;


/* @MapKey doesn't work at all. 
    org.hibernate.AnnotationException: Associated class not found: com.demo.Item
        at org.hibernate.cfg.annotations.MapBinder.bindKeyFromAssociationTable(MapBinder.java:116)
*/
@ElementCollection
@MapKey(name = "keyValue")
private Map<String, Item> items;

@ElementCollection
@CollectionTable(joinColumns = @JoinColumn(name = "code"))
@MapKeyJoinColumn(name = "keyValue")
private Map<String, Item> items;

@ElementCollection
@JoinColumn(name = "keyValue")
private Map<String, Item> items;

@ElementCollection
@CollectionTable(joinColumns = @JoinColumn(name = "code"))
@MapKeyJoinColumn(name = "keyValue")
@Column(name = "keyValue")
private Map<String, Item> items;

but the column name is always generated as items_key:

create table root_items (
    code int8 not null,
    other_value varchar(255),
    items_key varchar(255) not null,
    primary key (code, items_key)
);

I've also tried all the above combinations keeping keyValue in Item but then I only get and extra column:

create table root_items (
    code int8 not null,
    key_value varchar(255),
    other_value varchar(255),
    items_key varchar(255) not null,
    primary key (code, items_key)
);

Similar questions I've found but doesn't solve my problem:

  • @ElementCollection with Map<Entity, Embeddable> where Entity is a field of the Embeddable

  • Key & value column name overrides when mapping java.util.Map with JPA annotations

Is there anyway to force the column name to some custom value?

EDIT 1: I've found that if the map key is @Embeddable then I can achieve it. But I don't think it's a valid solution to achieve this. I would like to keep the map key as String

@Entity
public class Root {
    @Id
    private Long code;

    private String value;

    @ElementCollection
    private Map<ItemKey, Item> items;
}
@Embeddable
public class ItemKey {
    private String keyValue;
}

Is there anyway to force the column name to some custom value when the key is String?

like image 537
Tobías Avatar asked Feb 01 '26 08:02

Tobías


1 Answers

Finally I found it. It's as simple as that:

@Entity
public class Root {
    @Id
    private Long code;

    private String value;

    @ElementCollection
    @MapKeyColumn(name = "keyValue")
    private Map<String, Item> items;
}

I leave the answer in case it may help another one as lost as I. :P

like image 145
Tobías Avatar answered Feb 03 '26 20:02

Tobías



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!