我在使用JPA将mysql SET类型映射到Java Set时遇到了问题 为了说明我的问题,我构建了一个随机的例子
这是一个具有类型Set的列类型的表(即:它将是字符串的集合)
CREATE TABLE `MusicCD` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`period` ENUM('Classical', 'Modern','Antique') NOT NULL,
`genre` SET('horror','thriller','comedy','drama','romance') ,
PRIMARY KEY (`id`)
)
下面是用于映射的实体类
@Entity
@Table(name = "MusicCD")
class MusicCD {
private long id;
private Period period;
private Set<String> genre;
//other getter setters //
@Column(name = "genre")
@ElementCollection(targetClass = String.class, fetch = FetchType.EAGER)
public Set<String> getGenre() {
return genre;
}
public void setGenre(Set<String> genre) {
this.genre = genre;
}
}
使用此映射没有异常,但实体对象中的集合为空,因为JPA / hibernate发送的get查询会查询表MusicCD中的所有字段,但对于类型,它会向表MusicCD_genre发送单独的查询
当我看到sql架构时,会出现一个自动生成的表MusicCD_genre,它是空的。 在MusicCD上发送类型的sql select查询返回类型。 那么sql中的Set数据类型如何工作以及映射它的正确注释是什么?
更新 我也试过
@TypeDefs({@TypeDef(name = "javaSet", typeClass = HashSet.class)})
并使用
注释getter@Type(type = "javaSet")
但在反序列化期间,这不适用于EOFException。 这可能通过将HashSet替换为正确的类型来反序列化为。
答案 0 :(得分:2)
我知道这是一个老问题,但是我更喜欢在getter / setter中使用这些'MySQL特殊类型'列时最常用的是java代码。
@Entity
@Table(name = "MusicCD")
class MusicCD {
/*...*/
@Column(name = "genre")
private String genreStr;
/*...*/
public Set<String> getGenre() {
if(genreStr == null)
return Collections.emptySet();
else
return Collections.unmodifiableSet(
new HashSet<String>(Arrays.asList(genreStr.split(",")))
);
}
public void setGenre(Set<String> genre) {
if(genre == null)
genreStr = null;
else
genreStr = String.join(",", genre);
}
}
我使用Set的不可变版本,因为这样可以避免在不实际更改数据库的情况下尝试更改设置值。