I have a simple JPA mapping example including a map. A TestEntity has a map of SubEntity-Objects and some keys. I would have expected that the map keys are stored. Instead they are null. Here is the code:
@Entity
public class TestEntity {
@OneToMany
public Map<String, SubEntity> map = new HashMap<String, SubEntity>();
@Id
@GeneratedValue(strategy = AUTO)
protected long id;
public String name;
public TestEntity() {
}
public TestEntity(String name) {
this.name = name;
}
}
This is the subentity:
@Entity
public class SubEntity {
@Id
@GeneratedValue(strategy = AUTO)
protected long id;
public SubEntity() {
}
String subEntityName;
public SubEntity(String name) {
this.subEntityName = name;
}
}
And here is the test code:
EntityManager em = EntityManagerService.getEntityManager();
em.getTransaction().begin();
for (int i = 0; i < 10; i++) {
TestEntity e = new TestEntity("MyNameIs" + i);
for (int j = 0; j < 8; j++) {
SubEntity se = new SubEntity("IamNo" + j + "." + i);
e.map.put("Key" + i * 100 + j, se);
em.persist(se);
}
em.persist(e);
}
em.getTransaction().commit();
All Objects are created and stored. Just the key values in the mapping table are all null. Where is my mistake? I am using JPA2 with eclipselink2.4.1 and Derby 10.
JPA 2.0 supports collections of primitives through the @ElementCollection annotation that you can use in conjunction with the support of java.util.Map collections. Something like this should work:
@Entity
public class Example {
@Id long id;
// ....
@ElementCollection
@MapKeyColumn(name="name")
@Column(name="value")
@CollectionTable(name="example_attributes", joinColumns=@JoinColumn(name="example_id"))
Map<String, String> attributes = new HashMap<String, String>(); // maps from attribute name to value
}
Use @MapKey
to specify an attribute of the target entity (SubEntity) that serves as the key for the map.
Or use @MapKeyColumn
to specify that the key must be stored in an additional column, not mapped in SubEntity.
The javadoc provides examples.
Finally I found the explanation: It is a bug in eclipselink . The bug is reported for version 2.3.1. I have used 2.4.1 and it does not seem to be fixed. Here is a related question . The first answer helps a lot: Although the defaults for @JoinTable and @MapKeyColumn create the right tabels and columns, just add them explicitly. My example from above looks like that now:
@Entity
public class TestEntity {
@OneToMany
// add these annotations for a work-around
@JoinTable(name="TESTENTITY_SUBENTITY")
@MapKeyColumn(name = "MAP_KEY", table="TESTENTITY_SUBENTITY")
public Map<String, SubEntity> map = new HashMap<String, SubEntity>();
@Id
@GeneratedValue(strategy = AUTO)
protected long id;
public String name;
public TestEntity() {
}
public TestEntity(String name) {
this.name = name;
}
}
With these two additional lines the keys are stored. The created tables look like that .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.