0

我有一个简单的 JPA 映射示例,包括一个地图。一个 TestEntity 有一个 SubEntity-Objects 和一些键的映射。我本来希望存储地图键。相反,它们是空的。这是代码:

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

这是子实体:

@Entity
public class SubEntity {

    @Id
    @GeneratedValue(strategy = AUTO)
    protected long id;

    public SubEntity() {
    }

    String subEntityName;

    public SubEntity(String name) {
        this.subEntityName = name;
    }
}

这是测试代码:

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();

所有对象都被创建和存储。只是映射表中的键值都是空的。我的错误在哪里?我将 JPA2 与 eclipselink2.4.1 和 Derby 10 一起使用。

4

3 回答 3

0

JPA 2.0 通过 @ElementCollection 注释支持基元集合,您可以将其与 java.util.Map 集合的支持结合使用。像这样的东西应该工作:

@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

}
于 2013-08-17T11:59:48.940 回答
0

用于@MapKey指定作为地图键的目标实体(子实体)的属性。

或者用于@MapKeyColumn指定键必须存储在附加列中,而不是映射在 SubEntity 中。

javadoc 提供了示例。

于 2013-08-17T12:08:51.637 回答
0

最后我找到了解释:这是eclipselink中的一个错误。该错误是针对版本 2.3.1 报告的。我用过 2.4.1 似乎没有修复。这是一个相关的问题。第一个答案很有帮助:虽然 @JoinTable 和 @MapKeyColumn 的默认值创建了正确的表和列,但只需显式添加它们。我上面的例子现在看起来像这样:

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

使用这两条附加线存储密钥。创建的表看起来像这样

于 2013-08-23T20:14:24.697 回答