2013-08-17 83 views
0

我有一个简单的JPA映射示例,包括一个映射。 TestEntity具有SubEntity-Objects和一些密钥的映射。我会预料到地图密钥会被存储。相反,它们是空的。下面是代码:JPA2.0映射密钥没有存储

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

的所有对象。只是映射表中的键值全部为空。我的错误在哪里?我正在使用eclipselink2.4.1和Derby 10的JPA2。

+0

“相反,他们是。” - 什么? – contradictioned

回答

0

最后我找到了解释:这是eclipselink中的一个错误。该错误报告为版本2.3.1。我已经使用2.4.1,它似乎并没有修复。这是一个相关的question。第一个答案有很大帮助:尽管@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; 
    } 
} 

用这两个额外的行键存储。创建的表看起来像that

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", [email protected](name="example_id")) 
    Map<String, String> attributes = new HashMap<String, String>(); // maps from attribute name to value 

} 
+0

那么,这可能会起作用。但是我上面描述的问题与实体的地图有关:在我的示例中,地图具有非平凡的值。令人惊讶的是,所有的工作都很好 - 只是键不存储,而列包含空值。 –

0

使用@MapKey指定用作地图的主要目标实体(子实体)的属性。

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

javadoc提供了示例。

+0

这些值的默认值工作正常。对我来说,这个问题在eclipselink中看起来更像是一个问题。我会检查。 –