3、用XML和注解映射枚举在XML映射中,首先创建一个定制的类型定义:
<typedef class = "persistence.StringEnumUserType"
name = "rating">
<param name="enumClassName">auction.model.Rating</param>
</typedef>
现在可以在Comment类映射中使用名为rating的类型:
<property name = "rating"
column = "RATING"
type = "rating"
not-null = "true"
update = "false"
access = "field"/>
另一方面,可以依赖Java Persistence提供程序持久化枚举。如果在类型java.lang.Enum中的一个被注解的实体类中有一个属性(例如Comment中的rating),并且它没有标记为@Transient或者transient(Java关键字),Hibernate JPA实现必须毫无怨言地保持该属性为开箱即用;它有一个处理这个的内建类型。这个内建的映射类型在数据库中必须默认为枚举的一种表示法。两种最常见的选择是字符串表示法,就像通过定制类型或者有序表示法与原生的Hibernate实现一样。有序表示法保存选中的枚举选项的位置:例如,1为EXCELLENT,2为OK,3为BAD.数据库列也默认为一个数字列。可以在属性上通过Enumerated注解改变这个默认的枚举映射:
public class Comment{
…
@Enumerated(EnumType.STRING)
@Column(name = "RATING", nullable = false, updatable = false)
private Rating rating;
}
现在已经切换到了基于字符串的表示法,实际上是与你的定制类型可以读写的相同的表示法。也可以使用JPA XML描述符:
<entity class="auction.model.Item" access="PROPERTY">
<attributes>
…
<basic name = "rating">
<column name = "RATING" nullable = "false" updatable = "false"/>
<enumerated>STRING</enumerated>
</basic>
</attributes>
</entity>
4、用定制映射类型查询你可能遇到的进一步问题是在Hibernate查询中使用被枚举的类型。例如,考虑获取所有等级为"bad"的评语的HQL格式的下列查询:
Query q =
session.createQuery(
"from Comment c where c.rating = auction.model.Rating.BAD"
);
如果把枚举持久化为字符串,虽然这个查询也有效(查询解析器用枚举值作为常量),但是如果选择了有序表示法,它就不起作用了。必须使用一个绑定参数,并对比较式通过编程来设置等级值:
Query q =
session.createQuery("from Comment c where c.rating = :rating");
Properties params = new Properties();
params.put("enumClassname",
"auction.model.Rating");
q.setParameter("rating",Rating.BAD,
Hibernate.custom(StringEnumUserType.class, params)
);
本例的最后一行使用静态的辅助方法Hibernate.custom(),来把定制的映射类型转化为Hibernate Type;这是告诉Hibernate有关枚举映射,以及如何处理Rating.BAD值的一种简单方法。注意,你还必须告诉Hibernate有关被参数化的类型可能需要的任何初始化属性。