我正在尝试使用Hibernate映射java.util.Map,但似乎无法正确使用它。我正在使用Hibernate 4.2.8.Final和hibernate3-maven-plugin 2.2。最初我想要一个由枚举值键入的映射,以实体作为值,但无论我尝试什么,数据库定义都没有用hbm2ddl正确显示。所以,我尝试从我的JPA2书中尝试一个简单的例子,映射Map<String, String
。这就是我的做法(我只使用JPA注释(javax.annotation)):
@ElementCollection
@CollectionTable(name = "coll_table")
@MapKeyColumn(name = "something")
@Column(name = "somethingElse")
public Map<String, String> getSomething() {
return something;
}
当尝试执行hbm2ddl时,它失败了:
Execution default-cli of goal org.codehaus.mojo:hibernate3-maven-plugin:2.2:hbm2ddl failed: Could not determine type for: java.util.Map, at table: SomeTable, for columns: [org.hibernate.mapping.Column(somethingElse)] -> [Help 1]
所以,我在targetClass=String.class
注释中添加了@ElementCollection
(即使它不是必需的。)它没有帮助。
但是,回到我试图首先解决的问题,使用枚举键和实体值进行映射。
此映射(其中LetterType为枚举,Letter为实体):
@OneToMany
@MapKeyEnumerated(EnumType.ORDINAL)
public Map<LetterType, Letter> getLetters() {
return letter;
}
产生以下SQL:
create table Application_Letter (
Application_Id int not null,
letter_id int not null,
mapkey varbinary(255) null,
primary key (Application_Id, mapkey),
unique (letter_id)
);
不是一个令人震惊的结果,给定我的最小映射(有点奇怪的是,被定义为ORDINAL
的密钥应该存储在varbinary(255)
列的思想中。)但是当我尝试时扩展我遇到问题的更多选项,无论我尝试什么,我似乎无法使mapkey
列获得任何其他名称或类型!
此映射(Letter的属性为type
,类型为LetterType):
@OneToMany
@JoinTable(name = "application_letter",
joinColumns = @JoinColumn(name = "app_id"),
inverseJoinColumns = @JoinColumn(name = "letter_id"))
@MapKey(name = "type")
@MapKeyEnumerated(EnumType.STRING)
public Map<LetterType, Letter> getLetters() {
return letters;
}
收率:
create table application_letter (
app_id int not null,
letter_id int not null,
primary key (app_id, letter_id),
unique (letter_id)
);
所以它正在听我的一些注释,但它仍然得到关键部分错误(看起来它认为Letter的id属性是关键,而不是我指定的类型属性。)这导致我相信使用枚举值作为键有问题,所以我尝试了这个:
@OneToMany
@JoinTable(name = "application_letter_string",
joinColumns = @JoinColumn(name = "app_id"),
inverseJoinColumns = @JoinColumn(name = "letter_id"))
@MapKeyColumn(name = "letterType")
public Map<String, Letter> getLettersString() {
return lettersString;
}
现在我正在使用String
类型的键,并明确命名,这必须起作用。但不,结果是:
create table application_letter_string (
app_id int not null,
letter_id int not null,
mapkey varchar(255) null,
primary key (app_id, mapkey),
unique (letter_id)
);
至少它注意到密钥是String
,并使密钥列为varchar
,但我指定的名称无处可见。
这引出了我的最后一个问题:我在这里做错了什么,或者Hibernate处理Map
的方式根本不起作用? (无法在基元之间创建地图,无法创建基元 - &gt;实体地图,无法创建枚举 - &gt;实体地图,无法创建实体会员 - &gt;实体地图,剩余的选项不多。)