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?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With