简体   繁体   English

列类型的奇怪Hibernate异常

[英]Strange Hibernate exception with column type

I am getting Hibernate exception: 我得到Hibernate异常:

Wrong column type. 错误的列类型。 Found: bit, expected: BOOLEAN DEFAULT TRUE 发现:位,预期:BOOLEAN DEFAULT TRUE

I have class User: 我有班级用户:

package mypackage;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "USER")
public class User {

   @Id
   @GeneratedValue
   @Column(name = "ID", unique = true, nullable = false)
   private Long id;

   @Column(name = "STATUS", columnDefinition = "BOOLEAN DEFAULT TRUE", 
                               nullable = false)
   private Boolean status = Boolean.TRUE;

   // getters and setters
}

This works properly if Hibernate creates table itself in database. 如果Hibernate在数据库中创建表本身,这可以正常工作。 When 什么时候

<property name="hibernate.hbm2ddl.auto">create</property>

or 要么

<property name="hibernate.hbm2ddl.auto">create-drop</property>

But if 但如果

  1. I run my program and allow Hibernate to create this table 我运行我的程序并允许Hibernate创建此表
  2. then I change the value of hibernate.hbm2ddl.auto to the validate 然后我将hibernate.hbm2ddl.auto的值更改为validate
  3. and I run my program again with the table that has generated by Hibernate and with 然后我用Hibernate生成的表再次运行我的程序

     <property name="hibernate.hbm2ddl.auto">validate</property> 

so I get the exception: 所以我得到了例外:

org.hibernate.HibernateException: Wrong column type in dbtest.user for column STATUS. org.hibernate.HibernateException:dbtest.user中列STATUS的列类型错误。 Found: bit, expected: BOOLEAN DEFAULT TRUE 发现:位,预期:BOOLEAN DEFAULT TRUE

Any idea what could be the reason for this behavior of Hibernate and how can I fix it? 任何想法Hibernate的这种行为的原因是什么,我该如何解决它?

I use MySQL server 5.1 and Hibernate 4.0.1 . 我使用MySQL server 5.1Hibernate 4.0.1

My Run class is just two lines: 我的Run类只有两行:

 public class Run {

   public static void main(String[] main) {

     SessionFactory sessionFactory = 
                new AnnotationConfiguration().configure().buildSessionFactory();

     Session session = sessionFactory.getCurrentSession();
   }
 }

The structure of the table: 表的结构:

CREATE TABLE USER (
    ID BIGINT(20) NOT NULL AUTO_INCREMENT,
    STATUS TINYINT(1) NOT NULL DEFAULT 1,
    PRIMARY KEY (ID),
    UNIQUE INDEX ID (ID)
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM
ROW_FORMAT=DEFAULT
AUTO_INCREMENT=2

My hibernate.cfg : 我的hibernate.cfg

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="connection.url">jdbc:mysql://127.0.0.1:3306/dbtest</property>
    <property name="connection.username">root</property>
    <property name="connection.password">root</property>

    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="current_session_context_class">thread</property>
    <property name="connection.pool_size">5</property>
    <property name="hibernate.transaction.flush_before_completion">true</property>
    <property name="hibernate.transaction.auto_close_session">true</property>
    <property name="hibernate.hbm2ddl.auto">validate</property>
    <property name="hibernate.show_sql">false</property>
    <property name="hibernate.format_sql">true</property>
    <property name="hibernate.use_sql_comments">false</property>
    <property name="hibernate.connection.charSet">true</property>

    <mapping class="mypackage.User"/>
  </session-factory>
</hibernate-configuration>

Hibernate creates the table with type TINYINT and I do not intermeddle on to the database and do not make any changes in the table manually! Hibernate使用TINYINT类型创建表,我不介入数据库,也不要手动对表进行任何更改! I'm just change the hibernate.hbm2ddl.auto to the validate and nothing else. 我只是将hibernate.hbm2ddl.auto更改为validate而不是其他任何内容。

As the other guys already said: There is no boolean-column type in MySql. 正如其他人已经说过的:MySql中没有布尔列类型。 I had a similar problem and "created" an own dialect. 我有一个类似的问题,并“创造”了自己的方言。 It extends the default MySQL5Dialect and registers the stanard sql-type BOOLEAN to the MySql column type bit. 它扩展了默认的MySQL5Dialect,并将stanard sql-type BOOLEAN注册到MySql列类型位。

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

You can then use it by setting the dialect in your hibernate properties: hibernate.dialect=your.package.Mysql5BitBooleanDialect 然后,您可以通过在hibernate属性中设置方言来使用它:hibernate.dialect = your.package.Mysql5BitBooleanDialect

Hope this helps.. 希望这可以帮助..

private Boolean status = Boolean.TRUE;

Should result in a default value of true already. 应该导致默认值为true。

Another way of solving this problem is using: 解决此问题的另一种方法是使用:

@PrePersist
public void prePersist()
{
    if ( status == null )
    {
         status = Boolean.TRUE;
    }
}

Wild guess since I haven't used annotations form mapping, but here goes: 因为我没有使用注释形式映射,所以我猜测

That columnDefinition looks like explicitly telling hibernate to use boolean column type with default value true, but MySql doesn't have boolean type, so maybe 该columnDefinition看起来像显式告诉hibernate使用默认值为true的布尔列类型,但是MySql没有布尔类型,所以也许

columnDefinition = "BOOLEAN DEFAULT TRUE"

should be something like this 应该是这样的

columnDefinition = "tinyint DEFAULT 1"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM