使用 Hibernate Core 4.1.7、JPA 注释、java 1.7
易于理解的是有关 Map<String, Entity> 阅读 Hibernate doc on collections的示例,或 Map<String, String>此处(stackoverflow)。
很难找到Map<String, Set<String>>
关于为什么我在这里问这个问题的例子(甚至 Map<String, Map<String, String>> 只是为了好奇菊花)。
我想要的只是保存包含命名的多值属性(=帐户属性)的实体(帐户)。
我都使用 3 种实体类型:Account -> @OneToMany -> AccountAttribute -> @OneToMany -> AccountAttributeValue
但是用我自己的类包装原生 Java 类型对我来说似乎有点傻。克隆 Map<String, String> 示例我想要类似的东西
@Entity
public class Account {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="key")
private Long key;
@ElementCollection(fetch=FetchType.EAGER)
@JoinTable(name = "Attribute",
joinColumns = @JoinColumn(name = "fkAccount"))
@MapKeyColumn(name = "name")
// next line is working for Map<String, String>, but not here!
@Column(name = "value")
private Map<String, Set<String>> attributes = new HashMap<String, Set<String>>();
// ... omitting: constructor, getters, setters, toString()
}
这给了我
Initial SessionFactory creation failed: org.hibernate.MappingException: Could not determine type for: java.util.Set, at table: Attribute, for columns:[org.hibernate.mapping.Column(attributes)]
作为数据库布局,我创建了 2 个表。-Account
只有一个键指向外键的表 -Attribute
每行中包含命名值的表。
例如,对于多值属性,我认为它包含2 行相同fkAccount
但name
不同的行value
- 是的,我本可以更规范化,但我想在可接受的时间内读取我的数据 :-)
CREATE TABLE IF NOT EXISTS `foo`.`Account` (
`key` INT NOT NULL AUTO_INCREMENT ,
...
CREATE TABLE IF NOT EXISTS `foo`.`Attribute` (
`fkAccount` INT NOT NULL ,
`name` VARCHAR(45) NOT NULL ,
`value` VARCHAR(45) NOT NULL
...
任何提示或备用数据库布局建议表示赞赏。
编辑 -
汤姆(据我所知)为我工作的解决方案谢谢你们,1天的体验,解决方案!
我的问题中刚才提到的表格布局现在适用于此类。
@Entity
public class Account {
/* ... omitting "key", see as above */
/* NEW: now @CollectionTable
replaces @JoinTable / @MapKeyColumn / @Column from above
*/
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name="AccountAttribute",
joinColumns=@JoinColumn(name="fkAccount"))
private Set<AccountAttribute> attributes = null;
// ... omitting: constructor, getters, setters, toString()
}
和新的
@Embeddable
public class AccountAttribute {
@Column(name="attributeName")
private String attributeName = null;
@Column(name="attributeValue")
private String attributeValue = null;
// ... omitting: constructor, getters, setters, toString()
}