【问题标题】:"Found: bit, expected: boolean" after Hibernate 4 upgradeHibernate 4 升级后的“发现:位,预期:布尔值”
【发布时间】:2012-01-29 21:03:49
【问题描述】:

我正在尝试从 Hibernate 3.6.5 升级到 4.0(以及从 Spring 3.0.5 升级到 3.1,这是支持 Hibernate 4 所必需的)。

现在,对于 MySQL 和 HSQL,我遇到了持久布尔字段的问题:

Caused by: org.hibernate.HibernateException: 
Wrong column type in PUBLIC.PUBLIC.EVENT for column Checked. Found: bit, expected: boolean
    at org.hibernate.mapping.Table.validateColumns(Table.java:282)
    at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1268)
    at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:155)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:453)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1737)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1775)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:184)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:314)

JPA @Entity@Column 注解用于域对象,有问题的字段如下所示:

@Column(name = "Checked")
private boolean checked;

HSQL 架构:

Checked bit default 0 not null,

MySQL 架构:

`Checked` tinyint(1) NOT NULL default '0',

在坚持使用 Hibernate 4 时最直接的解决方法是什么?我应该更改数据库架构、Hibernate 配置还是域类注释?

我不知道之前的代码和配置是否完全“正确”,但至少它在 Hibernate 3 中运行良好。

【问题讨论】:

  • 使用 HSQL,将模式文件中的“bit”更改为“boolean”似乎会有所帮助(即,我遇到了另一个 Hibernate 4 问题)。不过这有点奇怪,因为HSQL documentation 给人的印象是 BOOLEAN 和 BIT 是等价的。

标签: java mysql hibernate hsqldb hibernate-4.x


【解决方案1】:

这已在此处的类似问题中得到解答:

Hibernate JPA, MySQL and TinyInt(1) for Boolean instead of bit or char

由于您同时使用 HSQL DB,您的问题可能会稍微复杂一些,但您可以看看并尝试一下!

【讨论】:

    【解决方案2】:

    我可以通过将transformedBitIsBoolean=true 添加到我的 MySQL 连接字符串来解决此问题。见这里:https://hibernate.atlassian.net/browse/HHH-6935

    【讨论】:

    • 这比编码为位要好得多:-)
    • 为我工作(Hibernate 4.1.x)。因为起初我并不清楚这里的意思是什么: In persistence.xml:
    【解决方案3】:

    发现问题 我也得到了 org.hibernate.HibernateException: Wrong column type ... 发现:位,预期:布尔

    在 Hibernate 4 中的 BooleanType 上,他们将 Ctor 更改为

    public BooleanType() {
        this( org.hibernate.type.descriptor.sql.BooleanTypeDescriptor.INSTANCE, BooleanTypeDescriptor.INSTANCE );
    }
    

    代替旧版本

    public BooleanType() {
        this( BitTypeDescriptor.INSTANCE, BooleanTypeDescriptor.INSTANCE );
    }
    

    【讨论】:

    • 嗯,有什么解决办法呢?引用我的问题:“在坚持使用 Hibernate 4 的同时解决这个问题的最直接的方法是什么?我应该更改数据库架构、Hibernate 配置还是域类注释?”
    • 这不是问题的答案。
    【解决方案4】:

    我遇到了同样的问题,我扩展了 Dialect 以考虑到 mysql 将 boolean 视为 bit 的别名这一事实。

    public class Mysql5BitBooleanDialect extends MySQL5Dialect{     
        public Mysql5BitBooleanDialect() {
            super();
            registerColumnType( java.sql.Types.BOOLEAN, "bit" );        
        }       
    }
    

    我不使用更长的 bit() 字段(例如表示 byte[]),所以这可能会破坏它。

    【讨论】:

    • 这似乎是 Hibernate 的 MySQL 方言中与类型相关的(另一个)大疏忽。当 4.0 发布时,我推迟了升级,我很惊讶它在一年后没有得到解决。但谢谢你的提示。每次我注释布尔字段时,扩展方言和更新 persistence.xml 似乎比添加 columnDefinition 要好得多。我使用 Hibernate 作为 JPA 实现,我希望尽可能保持非配置位与实现无关。
    • 然而 6 个月后问题仍然存在。最糟糕的是 hibernate2ddl 本身生成的模式使用 MySQL 的布尔值。因此 Hibernate 无法验证 Hibernate 生成的模式 :(
    • 最后应该在下一个版本(4.3.0)中更正:hibernate.atlassian.net/browse/HHH-6935
    【解决方案5】:

    我通过将columnDefinition = "BIT" 添加到@Column 行来解决这个问题。

    @Basic
    @Column(name = "B", columnDefinition = "BIT", length = 1)
    public boolean isB() {
        return b;
    }
    

    它在数据库中也被定义为“BIT(1)”。还与 TINYINT 合作。这是我找到的最简单的解决方案,因为更改非常小,无需触及数据库。

    使用:MySQL 服务器 5.5.13、Hibernate 4.1.1、JDK 1.6

    【讨论】:

    • Hibernate 4.3.0+ 版不再需要
    • 这个解决方案可以工作 - 但是它不能解决根本问题 - 这是 mysql 服务器本身 - 考虑按照stackoverflow.com/a/22200375/1694963中的建议将“transformedBitIsBoolean”标志添加到您的数据源 URL
    猜你喜欢
    • 2015-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多