hibernate auto create in-memory hsqldb приводит к тому, что последовательность не найдена

Я использую hibernate в качестве поставщика jpa и хочу, чтобы он создавал hsqldb в памяти при запуске, используя: hibernate.hbm2ddl.auto=create

Но по какой-то причине я получаю исключения, как показано ниже в моих журналах. Кажется, все работает иначе. Это проблема спящего режима или hsqldb?

Я ограничен использованием jpa 1, поэтому использую hsqldb 1.8.0.10 и hibernate 3.3.0.SP1.

Это похоже на: Внутренняя база данных HSQL жалуется на привилегии

ERROR - 4. Statement.executeUpdate(drop sequence DDS_EMAIL_STATUS_SEQ) FAILED! drop sequence DDS_EMAIL_STATUS_SEQ {FAILED after 0 msec}
java.sql.SQLException: Sequence not found in statement [drop sequence DDS_EMAIL_STATUS_SEQ]
    at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
    at org.hsqldb.jdbc.jdbcStatement.fetchResult(Unknown Source)
    at org.hsqldb.jdbc.jdbcStatement.executeUpdate(Unknown Source)
    at net.sf.log4jdbc.StatementSpy.executeUpdate(StatementSpy.java:694)
    at org.apache.commons.dbcp.DelegatingStatement.executeUpdate(DelegatingStatement.java:228)
    at org.apache.commons.dbcp.DelegatingStatement.executeUpdate(DelegatingStatement.java:228)
    at org.hibernate.tool.hbm2ddl.SchemaExport.execute(SchemaExport.java:383)
    at org.hibernate.tool.hbm2ddl.SchemaExport.drop(SchemaExport.java:358)
    at org.hibernate.tool.hbm2ddl.SchemaExport.execute(SchemaExport.java:258)
    at org.hibernate.tool.hbm2ddl.SchemaExport.create(SchemaExport.java:211)
    at org.hibernate.impl.SessionFactoryImpl.(SessionFactoryImpl.java:343)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1327)
    at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669)
    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:132)
    at org.apache.openejb.assembler.classic.PersistenceBuilder.createEntityManagerFactory(PersistenceBuilder.java:184)
    at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:490)
    at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:450)
    at org.apache.openejb.assembler.classic.Assembler.buildContainerSystem(Assembler.java:368)
    at org.apache.openejb.assembler.classic.Assembler.build(Assembler.java:280)
    at org.apache.openejb.OpenEJB$Instance.(OpenEJB.java:125)
    at org.apache.openejb.OpenEJB$Instance.(OpenEJB.java:60)
    at org.apache.openejb.OpenEJB.init(OpenEJB.java:271)
    at org.apache.openejb.OpenEJB.init(OpenEJB.java:250)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.openejb.loader.OpenEJBInstance.init(OpenEJBInstance.java:36)
    at org.apache.openejb.client.LocalInitialContextFactory.init(LocalInitialContextFactory.java:71)
    at org.apache.openejb.client.LocalInitialContextFactory.init(LocalInitialContextFactory.java:53)
    at org.apache.openejb.client.LocalInitialContextFactory.getInitialContext(LocalInitialContextFactory.java:42)
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
    at javax.naming.InitialContext.init(InitialContext.java:223)
    at javax.naming.InitialContext.(InitialContext.java:197)

person AmanicA    schedule 12.10.2010    source источник
comment
Все еще сталкиваетесь с этой проблемой?   -  person David Blevins    schedule 30.10.2010
comment
@David Большое спасибо за продолжение. Да, это все еще беспокоило меня, но теперь я понял, что заставило его распечатать. См. комментарий, который я добавил к ответу Паскаля.   -  person AmanicA    schedule 30.10.2010
comment
Здорово. Просто хотел убедиться, что о тебе позаботятся. Если есть какие-либо функции, которые вы хотели бы получить от OpenEJB в этом отношении, просто дайте мне знать.   -  person David Blevins    schedule 30.10.2010


Ответы (2)


Поскольку вы используете базу данных в памяти, неудивительно, что последовательность, как и любой другой объект базы данных, отсутствует во время экспорта. Но я не знаю, почему вы получаете такую ​​​​полную трассировку стека. Я только что попробовал базовый тестовый пример, и вот что я получаю:

16:27:07.708 [main] DEBUG o.h.tool.hbm2ddl.SchemaExport - Unsuccessful: drop sequence MY_ENTITY_SEQ
16:27:07.709 [main] DEBUG o.h.tool.hbm2ddl.SchemaExport - Sequence not found in statement [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";
}

Хотя не проверял.

person Pascal Thivent    schedule 12.10.2010
comment
Большое спасибо, что попробовали это. Теперь я понял, что org.lazyluke:log4jdbc-remix:0.2.4 — это тот, который распечатывает это. Если я закомментирую следующее из моих log4j.properties, эти трассировки стека исчезнут log4j.logger.jdbc.sqlonly=info . Я не совсем уверен, как мне избавиться от этого, может быть, я могу настроить log4j, чтобы как-то его пропустить. - person AmanicA; 30.10.2010

Вот метод, который мне нравится использовать для получения свежей базы данных в памяти при каждом тесте.

@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 для каждого теста.

person David Blevins    schedule 14.10.2010
comment
Спасибо, но, как указано в ответе Паскаля, проблема заключается в том, что спящий режим отбрасывает/создает последовательности, но ошибку действительно следует игнорировать. - person AmanicA; 30.10.2010