架构不会放在hbmddl.auto = create.drop上 [英] Schema is not dropped on hbmddl.auto = create.drop

查看:84
本文介绍了架构不会放在hbmddl.auto = create.drop上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 hbmddl.auto 设置在hibernate配置文件中创建并使用它在网络模式下连接到derby数据库(不嵌入,不知道如果这是相关的)。



这是我的 hibernate.cfg.xml

 <!DOCTYPE hibernate-configuration PUBLIC 
- // Hibernate / Hibernate配置DTD 3.0 // EN
http://www.hibernate.org /dtd/hibernate-configuration-3.0.dtd\">
< hibernate-configuration>

< session-factory>

<! - 数据库连接设置 - >
< property name =connection.driver_class> org.apache.derby.jdbc.ClientDriver< / property>
< property name =connection.url> jdbc:derby:// localhost:1527 / HibernateDb; create = true< / property>
< property name =connection.username> admin< / property>
< property name =connection.password> admin< / property>

<! - JDBC连接池(使用内置) - >
< property name =connection.pool_size> 1< / property>

<! - - SQL方言 - >
< property name =dialect> org.hibernate.dialect.DerbyDialect< / property>

<! - 禁用二级缓存 - >
< property name =cache.provider_class> org.hibernate.cache.NoCacheProvider< / property>

<! - 将所有执行的SQL回复到stdout - >
< property name =show_sql> true< / property>

<! - 在启动时删除并重新创建数据库模式 - >
< property name =hbm2ddl.auto> create-drop< / property>

<! - 给注释的实体类命名 - >
< mapping class =org.asif.javabrains.dto.UserDetails/>

< / session-factory>

< / hibernate-configuration>

但是当我运行使用这个aka服务类的java程序时,删除数据库并重新创建它。正如评论所说(我从hibernate示例中获取配置文件)。



~~~~ UPDATE ~~~~



我得出结论,hbm2ddl没有根据以下行为删除模式:

我有两个类,如下所示:

  @Entity 
public class UserDetails {

@Id @GeneratedValue(strategy = GenerationType.AUTO)
private int userId;
private String userName;
$ b @OneToMany
@JoinTable(name =USER_VEHICLE,
joinColumns = @ JoinColumn(name =USER_ID),
inverseJoinColumns = @JoinColumn(name = VEHICLE_ID)

私人收藏<车辆>车辆= new ArrayList< Vehicle>();
$ b / * getters and setters * /
}

  @Entity 
公共类车辆{
@Id @GeneratedValue
private int vehicleId;
私人字符串vehicleName;
@ManyToOne
@JoinColumn(name =USER_ID)
私人UserDetails用户;
$ b / * getters and setters * /
}

和相应的hibernate配置是

 <! -  boiler plate  - > 

<! - 在启动时删除并重新创建数据库模式 - >
< property name =hbm2ddl.auto>建立< / property>

<! - 给注释的实体类命名 - >
< mapping class =org.asif.javabrains.dto.UserDetails/>
< mapping class =org.asif.javabrains.dto.Vehicle/>

<! - 锅炉板 - >

现在,当我将上面的类更改为

  @Entity 
public class UserDetails {

@Id @GeneratedValue(strategy = GenerationType.AUTO)
private int userId;
private String userName;

@OneToMany(mappedBy =user)
private Collection< Vehicle>车辆= new ArrayList< Vehicle>();
//其余为相同

  @Entity 
公共类车辆{
@Id @GeneratedValue
private int vehicleId;
私人字符串vehicleName;
@ManyToOne
@JoinColumn(name =USER_ID)
私人UserDetails用户;
//休息是相同的

以下是打印到控制台

  SLF4J:未能加载类org.slf4j.impl.StaticLoggerBinder。 
SLF4J:默认为无操作(NOP)记录器实现
SLF4J:有关详细信息,请参阅http://www.slf4j.org/codes.html#StaticLoggerBinder。
Hibernate:插入到Vehicle(vehicleId,USER_ID,vehicleName)值(默认值,?)
Hibernate:插入到UserDetails(userId,userName)值(默认,?)
Hibernate:values identity_val_local() ?,?)
线程main中的异常org.hibernate.exception.SQLGrammarException:无法在org.hibernate.exception.SQLStateConverter中插入:[org.asif.javabrains.dto.Vehicle]
。转换(SQLStateConverter.java:92)
在org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
在org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java: 64)
。在org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2345)
。在org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2852)
在org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:71)
在org.hibernate.engine.ActionQ ueue.execute(ActionQueue.java:273)
在org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:320)
在org.hibernate.event.def.AbstractSaveEventListener.performSave( AbstractSaveEventListener.java:203)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:129)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:在org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56 210)

。在org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
。在org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
在org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdat eEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:713)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:701)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:697)
at org.asif.javabrains.hibernate.HibernateTest.main(HibernateTest.java:33)
导致:java .sql.SQLSyntaxErrorException:'USER_ID'不是表或VTI'ADMIN.VEHICLE'中的列。
at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown Source)
at org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
at org.apache.derby.client.am.SqlException.getSQLException .apache.derby.client.am.Connection.prepareStatement(Unknown Source)
at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:534)
at org.hibernate.jdbc.AbstractBatcher。 prepareStatement(AbstractBatcher.java:116)
at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:54)
... 16 more
引起:org.apache .derby.client.am.SqlException:'USER_ID'不是表或VTI'ADMIN.VEHICLE'中的列。
在org.apache.derby.client.am.Statement.completeSqlca(未知来源)
在org.apache.derby.client.net.NetStatementReply.parsePrepareError(未知来源)
在org .apache.derby.client.net.NetStatementReply.parsePRPSQLSTTreply(Unknown Source)
at org.apache.derby.client.net.NetStatementReply.readPrepareDescribeOutput(Unknown Source)
org.apache.derby.client .net.StatementReply.readPrepareDescribeOutput(来源不明)
在org.apache.derby.client.net.NetStatement.readPrepareDescribeOutput_(来源不明)
在org.apache.derby.client.am.Statement.readPrepareDescribeOutput (未知源)
在org.apache.derby.client.am.PreparedStatement.readPrepareDescribeInputOutput(未知源)
在org.apache.derby.client.am.PreparedStatement.flowPrepareDescribeInputOutput(未知源)
at org.apache.derby.client.am.PreparedStatement.prepare(Unknown Source)
at org.apache.derby.client.am.Connection.prepareState我想知道这是什么原因,但我不知道这是什么原因。手动删除表格并重新执行。这可能是导致此行为的原因。

解决方案

该评论实际上是不正确的。自很久以前以来,create-drop的真实行为与与创建相比,前者是在SessionFactory关闭时删除模式。 创建本身会执行评论所说的内容,即放弃架构并在启动时重新创建它。为了验证,设置org.hibernate日志记录将显示,通过create或create-drop,模式将被删除,然后在启动时创建:

  INFO  - 运行hbm2ddl模式导出
DEBUG - 导入文件未找到:/import.sql
INFO - 将生成的模式导出到数据库
TRACE - 总数检查出的连接:0
TRACE - 使用池连接的JDBC连接,池大小:0
DEBUG - alter table禁止删除约束FK103F39E150191
DEBUG - 不成功:alter table禁止删除约束FK103F39E150191
调试 - 未找到表格BAR; SQL语句:
alter table Bar drop约束FK103F39E150191 [42102-149]
DEBUG - drop table Bar如果存在的话
DEBUG - drop table Foo if exists
DEBUG - create table Bar默认情况下,生成的ID为整数标识,foo_id整数,主键(ID))
DEBUG - 创建表Foo(默认情况下生成的ID整数作为标识,主键(ID))
DEBUG - alter table Bar添加约束FK103F39E150191外键(foo_id)引用Foo
INFO - 模式导出完成

然而,关闭时(SessionFactory.close()),create给出

  INFO  - 关闭
INFO - 清理连接池:jdbc:h2:file:D:/ dev / projects / testbed / test-db-for-hibernate-create-drop

而使用create-drop时,您会看到

  INFO  - 关闭
INFO - 运行hbm2ddl模式导出
DEBUG - 导入文件未找到:/import.sql
INFO - 将生成的模式导出到数据库se
TRACE - 总检出连接数:0
TRACE - 使用池连接的JDBC连接,池大小:0
DEBUG - alter table Bar drop约束FK103F39E150191
DEBUG - drop table Bar如果存在
DEBUG - drop table Foo如果存在
INFO - 模式导出完成
TRACE - 返回连接到池,池大小:1
INFO - 清理连接池:jdbc: h2:file:D:/ dev / projects / testbed / test-db-for-hibernate-create-drop

您可以自己尝试:

  git clone git@github.com:zzantozz / testbed tmp 
cd tmp
mvn compile exec:java -Dexec.mainClass = rds.hibernate.Main -pl hibernate-create-drop


I am using hbmddl.auto set to create in the hibernate configuration file and using it to connect to the derby database in network mode (not embedded, don't know if that is relevant).

Here is my hibernate.cfg.xml

    <!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>

    <session-factory>

        <!-- Database connection settings -->
        <property name="connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>
        <property name="connection.url">jdbc:derby://localhost:1527/HibernateDb;create=true</property>
        <property name="connection.username">admin</property>
        <property name="connection.password">admin</property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.DerbyDialect</property>

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>

        <!-- Drop and re-create the database schema on startup -->
        <property name="hbm2ddl.auto">create-drop</property>

        <!-- Names the annotated entity class -->
        <mapping class="org.asif.javabrains.dto.UserDetails"/>

    </session-factory>

</hibernate-configuration>

But when i run the java program that is using this aka the service class, i doesn't seem to drop the database and recreate it. as the comment says ( i took the config file from the hibernate examples).

~~~~UPDATE~~~~

I concluded that hbm2ddl was not dropping the schema based on the following behaviour

I have 2 classes that look like as follows

@Entity
public class UserDetails {

    @Id @GeneratedValue(strategy=GenerationType.AUTO)
    private int userId;
    private String userName;

    @OneToMany
    @JoinTable(name="USER_VEHICLE",
               joinColumns=@JoinColumn(name="USER_ID"),
               inverseJoinColumns = @JoinColumn(name="VEHICLE_ID")
    )    
    private Collection<Vehicle> vehicles = new ArrayList<Vehicle>() ;

        /* getters and setters */
}

and

@Entity
public class Vehicle {
    @Id @GeneratedValue
    private int vehicleId;
    private String vehicleName;
    @ManyToOne
    @JoinColumn(name="USER_ID")
    private UserDetails user;

        /* getters and setters */
}

and the corresponding hibernate config is

 <!--boiler plate-->

   <!-- Drop and re-create the database schema on startup -->
    <property name="hbm2ddl.auto">create</property>

    <!-- Names the annotated entity class -->
    <mapping class="org.asif.javabrains.dto.UserDetails"/>
    <mapping class="org.asif.javabrains.dto.Vehicle"/>

  <!--boiler plate-->

Now when i change the above classes to

  @Entity
    public class UserDetails {

        @Id @GeneratedValue(strategy=GenerationType.AUTO)
        private int userId;
        private String userName;

        @OneToMany(mappedBy="user")
        private Collection<Vehicle> vehicles = new ArrayList<Vehicle>() ;
    //rest is same

and

@Entity
public class Vehicle {
    @Id @GeneratedValue
    private int vehicleId;
    private String vehicleName;
    @ManyToOne
    @JoinColumn(name="USER_ID")
    private UserDetails user;
      //rest is same

The following is printed to the console

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Hibernate: insert into UserDetails (userId, userName) values (default, ?)
Hibernate: values identity_val_local()
Hibernate: insert into Vehicle (vehicleId, USER_ID, vehicleName) values (default, ?, ?)
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not insert: [org.asif.javabrains.dto.Vehicle]
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:64)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2345)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2852)
    at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:71)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273)
    at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:320)
    at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:203)
    at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:129)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
    at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
    at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
    at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:713)
    at org.hibernate.impl.SessionImpl.save(SessionImpl.java:701)
    at org.hibernate.impl.SessionImpl.save(SessionImpl.java:697)
    at org.asif.javabrains.hibernate.HibernateTest.main(HibernateTest.java:33)
Caused by: java.sql.SQLSyntaxErrorException: 'USER_ID' is not a column in table or VTI 'ADMIN.VEHICLE'.
    at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown Source)
    at org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
    at org.apache.derby.client.am.Connection.prepareStatement(Unknown Source)
    at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:534)
    at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:116)
    at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:54)
    ... 16 more
Caused by: org.apache.derby.client.am.SqlException: 'USER_ID' is not a column in table or VTI 'ADMIN.VEHICLE'.
    at org.apache.derby.client.am.Statement.completeSqlca(Unknown Source)
    at org.apache.derby.client.net.NetStatementReply.parsePrepareError(Unknown Source)
    at org.apache.derby.client.net.NetStatementReply.parsePRPSQLSTTreply(Unknown Source)
    at org.apache.derby.client.net.NetStatementReply.readPrepareDescribeOutput(Unknown Source)
    at org.apache.derby.client.net.StatementReply.readPrepareDescribeOutput(Unknown Source)
    at org.apache.derby.client.net.NetStatement.readPrepareDescribeOutput_(Unknown Source)
    at org.apache.derby.client.am.Statement.readPrepareDescribeOutput(Unknown Source)
    at org.apache.derby.client.am.PreparedStatement.readPrepareDescribeInputOutput(Unknown Source)
    at org.apache.derby.client.am.PreparedStatement.flowPrepareDescribeInputOutput(Unknown Source)
    at org.apache.derby.client.am.PreparedStatement.prepare(Unknown Source)
    at org.apache.derby.client.am.Connection.prepareStatementX(Unknown Source)
    ... 20 more

This seems to go away when i manually delete the tables and execute again. What could be causing this behavior.

解决方案

That comment is actually incorrect. Since quite a long time ago, the true behavior of "create-drop" as compared to just "create" is that the former drops the schema when the SessionFactory is closed. "create" itself does what the comment says, which is to drop the schema and recreate it on startup. For verification, setting "org.hibernate" logging to trace will show that with either "create" or "create-drop", the schema is dropped and then created at startup:

INFO - Running hbm2ddl schema export
DEBUG - import file not found: /import.sql
INFO - exporting generated schema to database
TRACE - total checked-out connections: 0
TRACE - using pooled JDBC connection, pool size: 0
DEBUG - alter table Bar drop constraint FK103F39E150191
DEBUG - Unsuccessful: alter table Bar drop constraint FK103F39E150191
DEBUG - Table "BAR" not found; SQL statement:
alter table Bar drop constraint FK103F39E150191 [42102-149]
DEBUG - drop table Bar if exists
DEBUG - drop table Foo if exists
DEBUG - create table Bar (id integer generated by default as identity, foo_id integer, primary key (id))
DEBUG - create table Foo (id integer generated by default as identity, primary key (id))
DEBUG - alter table Bar add constraint FK103F39E150191 foreign key (foo_id) references Foo
INFO - schema export complete

However, on shutdown (SessionFactory.close()), the "create" gives

INFO - closing
INFO - cleaning up connection pool: jdbc:h2:file:D:/dev/projects/testbed/test-db-for-hibernate-create-drop

whereas with "create-drop", you'll see

INFO - closing
INFO - Running hbm2ddl schema export
DEBUG - import file not found: /import.sql
INFO - exporting generated schema to database
TRACE - total checked-out connections: 0
TRACE - using pooled JDBC connection, pool size: 0
DEBUG - alter table Bar drop constraint FK103F39E150191
DEBUG - drop table Bar if exists
DEBUG - drop table Foo if exists
INFO - schema export complete
TRACE - returning connection to pool, pool size: 1
INFO - cleaning up connection pool: jdbc:h2:file:D:/dev/projects/testbed/test-db-for-hibernate-create-drop

You can try it yourself:

git clone git@github.com:zzantozz/testbed tmp
cd tmp
mvn compile exec:java -Dexec.mainClass=rds.hibernate.Main -pl hibernate-create-drop

这篇关于架构不会放在hbmddl.auto = create.drop上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆