Hibernate 的值为“create”的“hbm2ddl.auto”属性不是重新创建表

Posted

技术标签:

【中文标题】Hibernate 的值为“create”的“hbm2ddl.auto”属性不是重新创建表【英文标题】:Hibernate's 'hbm2ddl.auto' property with value 'create' is not re-creating table 【发布时间】:2012-06-02 11:20:58 【问题描述】:

我正在处理我的first simple Hibernate application。问题的症结在于,我重命名了持久类的成员(对所有其他部分进行了适当的更改)并重新运行应用程序。由于 'hbm2ddl.auto' 属性在配置 xml 中被分配了 'create' 值,Hibernate 预计会在每次运行时创建新表,但它并没有这样做。以下是详细信息:

类:

    public class Event 
    private Long id;

    private String title;
    private Date date;

    public Event() 
        // this form used by Hibernate
    

    public Event(String title, Date date) 
        // for application use, to create new events
        this.title = title;
        this.date = date;
    

    public Long getId() 
        return id;
    

    private void setId(Long id) 
        this.id = id;
    

    public Date getDate() 
        return date;
    

    public void setDate(Date date) 
        this.date = date;
    

    public String getTitle() 
        return title;
    

    public void setTitle(String title) 
        this.title = title;
    

Event.hbm.xml:

<hibernate-mapping package="org.hibernate.tutorial.hbm">

<class name="Event" table="EVENTS">
    <id name="id" column="EVENT_ID">
        <generator class="increment"/>
    </id>
    <property name="date" type="timestamp" column="EVENT_DATE"/>
    <property name="title"/>
</class>

hibernate.cfg.xml 等具有以下条目:

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

主要课程:

public class EventManager 

public static void main(String[] args) 

    EventManager mgr = new EventManager();

    List events = mgr.listEvents();
for (int i = 0; i < events.size(); i++) 
    Event theEvent = (Event) events.get(i);
        System.out.println( "Event: " + theEvent.getTitle() + " Time: " + theEvent.getDate() );
    

    HibernateUtil.getSessionFactory().close();



private List listEvents() 
    Session session = HibernateUtil.getSessionFactory().getCurrentSession();
    session.beginTransaction();
    List result = session.createQuery("from Event").list();
    session.getTransaction().commit();
    return result;
 

上面的代码按预期工作。只是为了测试“hbm2ddl.auto”属性,我已将 Event 类中的“title”成员更改为“title1”。并且,更新了 setter 和 getter 方法以及所有引用(在映射 xml、Event 和 EventManager 类中)。遵守没有错误。但是,当我尝试运行应用程序时,我看到以下异常:

线程“主”org.hibernate.exception.SQLGrammarException 中的异常:“字段列表”中的未知列“event0_.title1” 在 org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:82) 在 org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49) 在 org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125) 在 org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110) 在 org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129) 在 org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81) 在 $Proxy6.executeQuery(未知来源) 在 org.hibernate.loader.Loader.getResultSet(Loader.java:1953) 在 org.hibernate.loader.Loader.doQuery(Loader.java:829) 在 org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:289) 在 org.hibernate.loader.Loader.doList(Loader.java:2438) 在 org.hibernate.loader.Loader.doList(Loader.java:2424) 在 org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2254) 在 org.hibernate.loader.Loader.list(Loader.java:2249) 在 org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:470) 在 org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:355) 在 org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:195) 在 org.hibernate.internal.SessionImpl.list(SessionImpl.java:1248) 在 org.hibernate.internal.QueryImpl.list(QueryImpl.java:101) 在 org.hibernate.tutorial.hbm.EventManager.listEvents(EventManager.java:56) 在 org.hibernate.tutorial.hbm.EventManager.main(EventManager.java:20) 引起:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:“字段列表”中的未知列“event0_.title1” 在 sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 在 sun.reflect.NativeConstructorAccessorImpl.newInstance(未知来源) 在 sun.reflect.DelegatingConstructorAccessorImpl.newInstance(未知来源) 在 java.lang.reflect.Constructor.newInstance(未知来源) 在 com.mysql.jdbc.Util.handleNewInstance(Util.java:409) 在 com.mysql.jdbc.Util.getInstance(Util.java:384) 在 com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1054) 在 com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3562) 在 com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3494) 在 com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1960) 在 com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2114) 在 com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2696) 在 com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2105) 在 com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2264) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(未知来源) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(未知来源) 在 java.lang.reflect.Method.invoke(未知来源) 在 org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122) ... 16 更多

错误指向以下行的 EventManager 类:

List result = session.createQuery("from Event").list();

由于 'hbm2ddl.auto' 属性在配置 xml 中被分配了 'create' 值,Hibernate 预计会在每次运行时创建新表,但它并没有这样做。请帮助解决问题。

提前致谢。

【问题讨论】:

【参考方案1】:

尝试指定hibernate.hbm2ddl.auto=create 而不仅仅是hbm2ddl.auto=create

这就是documentation 的用途。

【讨论】:

Alex,1/2:非常感谢您的回复,帮助跟踪问题。我尝试了你的建议,但是我看到了同样的例外。这次我仔细查看了整个日志记录,我注意到以下几行:错误:HHH000389:不成功:如果存在则删除表事件错误:无法删除或更新父行:外键约束失败 Alex,2/2:所以,最后一个错误声明清楚地指出了我之前忽略的问题。在处理示例时,我创建了 PERSON 表,该表与 EVENTS 表有 many2many 关系,这是成功的。然后,我尝试通过执行 OP 中提到的操作并在 PERSON 表的配置文件中注释映射条目来更改“标题”成员。 Hibernate 报告了错误,但是,我忽略了。由于我是新成员,我不能投票,否则我肯定会投票。无论如何,再次感谢。 但是如果你使用create,那么你可能会丢失数据,因为它可能会丢失当前数据。更新应该可以工作。 很棒的小技巧。只是让我头疼不已。 +1 为避免其他同类错误,请使用org.hibernate.cfg.AvailableSettings 和他的静态属性【参考方案2】:

尝试&lt;property name="hibernate.hbm2ddl.auto"&gt;create&lt;/property&gt; 而不是&lt;property name="hbm2ddl.auto"&gt;create&lt;/property&gt;

【讨论】:

以上是关于Hibernate 的值为“create”的“hbm2ddl.auto”属性不是重新创建表的主要内容,如果未能解决你的问题,请参考以下文章

使用db.Create和db.FirstOrCreate将数据保存到数据库时,“ID”列的值为“0”

hibernate 一对多双向关联 外键值为空 怎么结决?

Hbase 创建表 插入数据Hb

Hibernate hbm2ddl.auto、可能的值以及它们的作用

如何修改mysql主键的值为自增

Hibernate延迟加载