为什么hibernate将tinyint(1)映射到java.lang.Boolean?

时间:2014-09-25 15:12:30

标签: java mysql hibernate enums

考虑Java中的以下枚举:

public enum Color {
    RED,
    GREEN
}

JPA实体中的定义

@Column(name = "COLOR")
private Color color;

和MySQL DDL:

`COLOR` tinyint(1) NOT NULL

为什么Hibernate 3.5似乎总是将tinyint(1)映射到java.lang.Boolean,导致以下异常:

java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.String
    at org.hibernate.type.EnumType.nullSafeGet(EnumType.java:119)
    at org.hibernate.type.CustomType.nullSafeGet(CustomType.java:132)
    at org.hibernate.type.AbstractType.hydrate(AbstractType.java:105)
    at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2267)
    at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1423)
    at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1351)
    at org.hibernate.loader.Loader.getRow(Loader.java:1251)
    at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:619)
    at org.hibernate.loader.Loader.doQuery(Loader.java:745)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:270)
    at org.hibernate.loader.Loader.doList(Loader.java:2294)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2172)
    at org.hibernate.loader.Loader.list(Loader.java:2167)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:448)
    at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:363)
    at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1258)
    at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
    at org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:264)

这似乎可以通过将DDL更改为tinyint(2)来轻松修复。但是,我想知道这是否有意,以及为什么hibernate映射到布尔值,即使它应该知道这应该映射为枚举。

2 个答案:

答案 0 :(得分:3)

根据the mysql jdbc type mapping,不仅是这种预期的行为,而且还有记录。严格地说,Hibernate没有进行映射,jdbc驱动程序是。如果您认为应该更改此行为,则可以file a bug针对mysql并提出案例。

答案 1 :(得分:1)

可以编写自定义UserType来告诉hibernate将tinyint(1)映射到枚举

class EnumUserType<T extends Enum<T>> implements UserType { ... }

您只需要实现nullSafeSetnullSafeGet方法,将枚举映射到结果集中的整数。

然后将“类型”注释添加到“实体”列

@org.hibernate.annotations.Type(type = "com.myco.EnumUserType")

当然你可以通过将tinyInt1isBit JDBC connection property设置为false来告诉mysql不要将tinyint(1)映射到一点,但这会影响你的所有tinyint(1)。