【问题标题】:hibernate auto create in-memory hsqldb causes Sequence not found休眠自动创建内存中的hsqldb导致找不到序列
【发布时间】:2011-04-24 08:46:03
【问题描述】:

我使用 hibernate 作为我的 jpa 提供程序并希望它创建一个 启动时内存中的 hsqldb 使用: hibernate.hbm2ddl.auto=创建

但由于某种原因,我的日志中出现如下异常。 事情似乎并非如此。是hibernate还是hsqldb的问题?

我仅限于使用 jpa 1,所以我正在使用 hsqldb 1.8.0.10 和休眠 3.3.0.SP1

这类似于: Internal HSQL database complains about privileges

错误 - 4. Statement.executeUpdate(删除序列 DDS_EMAIL_STATUS_SEQ)失败!删除序列 DDS_EMAIL_STATUS_SEQ {0 毫秒后失败} java.sql.SQLException:在语句中找不到序列 [删除序列 DDS_EMAIL_STATUS_SEQ] 在 org.hsqldb.jdbc.Util.sqlException(未知来源) 在 org.hsqldb.jdbc.jdbcStatement.fetchResult(未知来源) 在 org.hsqldb.jdbc.jdbcStatement.executeUpdate(未知来源) 在 net.sf.log4jdbc.StatementSpy.executeUpdate(StatementSpy.java:694) 在 org.apache.commons.dbcp.DelegatingStatement.executeUpdate(DelegatingStatement.java:228) 在 org.apache.commons.dbcp.DelegatingStatement.executeUpdate(DelegatingStatement.java:228) 在 org.hibernate.tool.hbm2ddl.SchemaExport.execute(SchemaExport.java:383) 在 org.hibernate.tool.hbm2ddl.SchemaExport.drop(SchemaExport.java:358) 在 org.hibernate.tool.hbm2ddl.SchemaExport.execute(SchemaExport.java:258) 在 org.hibernate.tool.hbm2ddl.SchemaExport.create(SchemaExport.java:211) 在 org.hibernate.impl.SessionFactoryImpl.(SessionFactoryImpl.java:343) 在 org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1327) 在 org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867) 在 org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669) 在 org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:132) 在 org.apache.openejb.assembler.classic.PersistenceBuilder.createEntityManagerFactory(PersistenceBuilder.java:184) 在 org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:490) 在 org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:450) 在 org.apache.openejb.assembler.classic.Assembler.buildContainerSystem(Assembler.java:368) 在 org.apache.openejb.assembler.classic.Assembler.build(Assembler.java:280) 在 org.apache.openejb.OpenEJB$Instance.(OpenEJB.java:125) 在 org.apache.openejb.OpenEJB$Instance.(OpenEJB.java:60) 在 org.apache.openejb.OpenEJB.init(OpenEJB.java:271) 在 org.apache.openejb.OpenEJB.init(OpenEJB.java:250) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在 java.lang.reflect.Method.invoke(Method.java:597) 在 org.apache.openejb.loader.OpenEJBInstance.init(OpenEJBInstance.java:36) 在 org.apache.openejb.client.LocalInitialContextFactory.init(LocalInitialContextFactory.java:71) 在 org.apache.openejb.client.LocalInitialContextFactory.init(LocalInitialContextFactory.java:53) 在 org.apache.openejb.client.LocalInitialContextFactory.getInitialContext(LocalInitialContextFactory.java:42) 在 javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667) 在 javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288) 在 javax.naming.InitialContext.init(InitialContext.java:223) 在 javax.naming.InitialContext.(InitialContext.java:197)

【问题讨论】:

  • 仍然遇到这个问题?
  • @David 非常感谢您的跟进。是的,它仍然困扰着我,但我现在知道是什么导致它被打印出来了。请参阅我添加到 Pascal 答案中的评论。
  • 太棒了。只是想确保你得到照顾。如果您希望 OpenEJB 在这方面有什么特性,请告诉我。

标签: java hibernate jpa hsqldb openejb


【解决方案1】:

这是我喜欢使用的一种技术,用于在每次测试时获取一个新的内存数据库。

@Override
public void setUp() throws Exception {
    Properties p = new Properties();
    p.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.LocalInitialContextFactory");
    p.put("movieDatabase", "new://Resource?type=DataSource");
    p.put("movieDatabase.JdbcDriver", "org.hsqldb.jdbcDriver");
    p.put("movieDatabase.JdbcUrl", "jdbc:hsqldb:mem:moviedb" + System.currentTimeMillis());
    p.put("openejb.embedded.initialcontext.close", "DESTROY");

    initialContext = new InitialContext(p);
}

@Override
protected void tearDown() throws Exception {
    initialContext.close();
}

基本上,通过附加 System.currentTimeMillis() 来提供唯一的数据库名称,并为每个测试重新构建嵌入式容器。

让您不必在测试后进行清理,但每次测试都不需要新的 jvm。

【讨论】:

  • 谢谢,但正如 Pascal 的回答中所述,问题在于休眠删除/创建序列,但实际上应该忽略该错误。
【解决方案2】:

由于您使用的是内存数据库,因此与任何其他数据库对象一样,序列在导出时不存在也就不足为奇了。但我不知道为什么你会得到这样的完整堆栈跟踪。我刚刚尝试了一个基本的测试用例,这就是我得到的:

16:27:07.708 [main] 调试 o.h.tool.hbm2ddl.SchemaExport - 不成功:删除序列 MY_ENTITY_SEQ 16:27:07.709 [main] DEBUG o.h.tool.hbm2ddl.SchemaExport - 在语句 [drop sequence MY_ENTITY_SEQ] 中找不到序列

换句话说,它默默地“失败”。

也许您可以尝试扩展HSQLDialect 并覆盖以下方法:

protected String getDropSequenceString(String sequenceName) {
    return "drop sequence " + sequenceName;
}

进入:

protected String getDropSequenceString(String sequenceName) {
    return "drop sequence " + sequenceName + " if exists";
}

虽然没有测试。

【讨论】:

  • 非常感谢您尝试这个。我现在发现 org.lazyluke:log4jdbc-remix:0.2.4 是打印出来的那个。如果我从 log4j.properties 中注释掉以下内容,那么这些堆栈跟踪将消失 "log4j.logger.jdbc.sqlonly=info" 。我不太确定如何摆脱它,也许我可以配置 log4j 以某种方式跳过它。
猜你喜欢
  • 2014-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-05
  • 2012-09-18
  • 2016-01-03
  • 1970-01-01
相关资源
最近更新 更多