【问题标题】:why does hibernate map tinyint(1) to a java.lang.Boolean?为什么休眠将 tinyint(1) 映射到 java.lang.Boolean?
【发布时间】:2014-11-20 10:21:44
【问题描述】:

考虑 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) 轻松解决。但是,我想知道这是否是有意的以及为什么休眠映射到布尔值,即使它应该知道这应该映射为枚举。

【问题讨论】:

  • mysql 以前不支持 'bit' 字段,将它们翻译成tinyint(1)。许多接口库被硬编码以将 tinyint(1) 视为布尔值以进行补偿。
  • 你试过 columnDefinition 吗?

标签: java mysql hibernate enums


【解决方案1】:

根据the mysql jdbc type mapping,这不仅是预期的行为,而且已记录在案。严格来说,Hibernate 不是在做映射,而是 jdbc 驱动。不过,如果您认为应该改变这种行为,您可以 file a bug 反对 mysql 并提出理由。

【讨论】:

    【解决方案2】:

    可以编写一个自定义的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)。

    【讨论】:

      猜你喜欢
      • 2011-12-23
      • 1970-01-01
      • 2015-08-31
      • 1970-01-01
      • 2014-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多