Hibernate Core 4.1.7、JPAアノテーション、java1.7を使用
簡単に説明できるのは、コレクションのHibernateドキュメントを読み取るMap <String、Entity> 、またはここにある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)]
DBレイアウトとして、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
...
ヒントや代替のDBレイアウトの提案をいただければ幸いです。
編集-
トムからの解決された解決策(私が理解している限り)私のために働いてくれてありがとうみんな、なんて経験、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()
}
とNEW
@Embeddable
public class AccountAttribute {
@Column(name="attributeName")
private String attributeName = null;
@Column(name="attributeValue")
private String attributeValue = null;
// ... omitting: constructor, getters, setters, toString()
}