【问题标题】:Play Framework: Error getting sequence nextval using H2 in-memory databasePlay Framework:使用 H2 内存数据库获取序列 nextval 时出错
【发布时间】:2012-06-03 10:20:43
【问题描述】:

正如标题所示,我在使用内存中带有 H2 的 FakeApplication 运行 Play 2.0.1 测试时遇到错误。

我设置了一个基本的单元测试:

public class ModelTest {
    @Test
    public void checkThatIndustriesExist() {
        running(fakeApplication(inMemoryDatabase()), new Runnable() {
            public void run() {
                Industry industry = new Industry();
                industry.name = "Some name";
                industry.shortname = "some-name";
                industry.save();
                assertThat(Industry.find.all()).hasSize(1);
            }
        });
    }

这会产生以下异常:

[info] test.ModelTest
[error] Test test.ModelTest.checkThatIndustriesExist failed: Error getting sequence nextval
[error]     at com.avaje.ebean.config.dbplatform.SequenceIdGenerator.getMoreIds(SequenceIdGenerator.java:213)
[error]     at com.avaje.ebean.config.dbplatform.SequenceIdGenerator.loadMoreIds(SequenceIdGenerator.java:163)
[error]     at com.avaje.ebean.config.dbplatform.SequenceIdGenerator.nextId(SequenceIdGenerator.java:118)
[error]     at com.avaje.ebeaninternal.server.deploy.BeanDescriptor.nextId(BeanDescriptor.java:1218)
[error]     at com.avaje.ebeaninternal.server.persist.DefaultPersister.setIdGenValue(DefaultPersister.java:1304)
[error]     at com.avaje.ebeaninternal.server.persist.DefaultPersister.insert(DefaultPersister.java:403)
[error]     at com.avaje.ebeaninternal.server.persist.DefaultPersister.saveEnhanced(DefaultPersister.java:345)
[error]     at com.avaje.ebeaninternal.server.persist.DefaultPersister.saveRecurse(DefaultPersister.java:315)
[error]     at com.avaje.ebeaninternal.server.persist.DefaultPersister.save(DefaultPersister.java:282)
[error]     at com.avaje.ebeaninternal.server.core.DefaultServer.save(DefaultServer.java:1577)
[error]     at com.avaje.ebeaninternal.server.core.DefaultServer.save(DefaultServer.java:1567)
[error]     at com.avaje.ebean.Ebean.save(Ebean.java:538)
[error]     at play.db.ebean.Model.save(Model.java:76)
[error]     at test.ModelTest$1.run(ModelTest.java:24)
[error]     at play.test.Helpers.running(Helpers.java:277)
[error]     at test.ModelTest.checkThatIndustriesExist(ModelTest.java:21)
[error]     ...
[error] Caused by: org.h2.jdbc.JdbcSQLException: Syntax Fehler in SQL Befehl "SELECT INDUSTRY_SEQ.NEXTVAL UNION[*] SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL "; erwartet "identifier"
[error] Syntax error in SQL statement "SELECT INDUSTRY_SEQ.NEXTVAL UNION[*] SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL "; expected "identifier"; SQL statement:
[error] select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval [42001-158]
[error]     at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
[error]     at org.h2.message.DbException.get(DbException.java:169)
[error]     at org.h2.message.DbException.getSyntaxError(DbException.java:194)
[error]     at org.h2.command.Parser.readColumnIdentifier(Parser.java:2777)
[error]     at org.h2.command.Parser.readTermObjectDot(Parser.java:2336)
[error]     at org.h2.command.Parser.readTerm(Parser.java:2453)
[error]     at org.h2.command.Parser.readFactor(Parser.java:2035)
[error]     at org.h2.command.Parser.readSum(Parser.java:2022)
[error]     at org.h2.command.Parser.readConcat(Parser.java:1995)
[error]     at org.h2.command.Parser.readCondition(Parser.java:1860)
[error]     at org.h2.command.Parser.readAnd(Parser.java:1841)
[error]     at org.h2.command.Parser.readExpression(Parser.java:1833)
[error]     at org.h2.command.Parser.parseSelectSimpleSelectPart(Parser.java:1746)
[error]     at org.h2.command.Parser.parseSelectSimple(Parser.java:1778)
[error]     at org.h2.command.Parser.parseSelectSub(Parser.java:1673)
[error]     at org.h2.command.Parser.parseSelectUnion(Parser.java:1518)
[error]     at org.h2.command.Parser.parseSelect(Parser.java:1506)
[error]     at org.h2.command.Parser.parsePrepared(Parser.java:405)
[error]     at org.h2.command.Parser.parse(Parser.java:279)
[error]     at org.h2.command.Parser.parse(Parser.java:251)
[error]     at org.h2.command.Parser.prepareCommand(Parser.java:217)
[error]     at org.h2.engine.Session.prepareLocal(Session.java:415)
[error]     at org.h2.engine.Session.prepareCommand(Session.java:364)
[error]     at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1119)
[error]     at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:71)
[error]     at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:267)
[error]     at com.jolbox.bonecp.ConnectionHandle.prepareStatement(ConnectionHandle.java:820)
[error]     at com.avaje.ebean.config.dbplatform.SequenceIdGenerator.getMoreIds(SequenceIdGenerator.java:193)
[error]     ... 80 more

我的模型如下所示:

@Entity
@Table(name = "industry")
public class Industry extends Model {
    @Id public Long id;
    public String name;
    public String shortname;

    // called in the view to trigger lazy-loading
    public String getName() {
        return name;
    }

    public static Finder<Long, Industry> find = new Finder<Long, Industry>(Long.class, Industry.class);
}

...最后是我最初进化的相关部分:

create table industry (
    id        bigint not null,
    name      varchar(255),
    shortname varchar(255),
    constraint pk_industry primary key (id)
}

create sequence industry_seq start with 1000;

在我的 PostgreSQL 数据库上运行一切正常,从我的角度来看,代码与 Play2.0 Computer Database Sample 没有任何不同。

我很乐意提供任何帮助 - 谢谢!

问候, 亚历克斯

【问题讨论】:

    标签: jdbc playframework-2.0 h2 ebean


    【解决方案1】:

    问题已解决,方法如下:

    • 在调用 inMemoryDatabase() 之前,我提供了自己的配置
    • 数据库的名称是“test”,而不是调用 inMemoryDatabase() 时使用的“default”
    • 因为我没有在 conf/evolutions/test 中保留进化,但只在 conf/evolutions/default 中没有创建架构
    • 我不得不清理应用程序,因为在更改为 inMemoryDatabase() 后未应用“默认”配置

    【讨论】:

    • 我会的;需要再等 23 小时,直到我被允许这样做。
    【解决方案2】:

    仅使用您的代码和一个我无法重现的新 Play 2.0.1 项目。这是我的代码和配置 with 导入。由于类不是问题,我的猜测是您使用 evolutionplugin=disabled 关闭了进化,并且您的数据库进化永远不会被应用,因此您的异常中出现了“预期的标识符”。

    如上所述,

    编辑禁用数据库演变会产生与您遇到的相同的异常,请参见底部。

    Edit-2this blogpost 的作者描述了如何手动应用进化。看起来不太性感,但我应该每个项目只需要实现一次该基类。如果有人知道框架内更优雅的东西,请告诉。

    Ebean Evolution(自动生成):

    create table industry (   
      id              bigint not null,  
      name            varchar(255),   shortname                
      varchar(255),   constraint pk_industry primary key (id)) ;
      create sequence industry_seq;
    ;
    

    我的模特行业

    package models;
    
    import play.db.ebean.Model;
    
    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.Table;
    
    @Entity
    @Table(name = "industry")
    public class Industry extends Model {
        @Id
        public Long id;
        public String name;
        public String shortname;
    
        // called in the view to trigger lazy-loading
        public String getName() {
            return name;
        }
    
        public static Finder<Long, Industry> find 
               = new Model.Finder<Long, Industry>(Long.class, Industry.class);
    }
    

    我的单元测试

    package models;
    
    import org.junit.Test;
    
    import java.util.List;
    import java.util.Map;
    
    import static org.fest.assertions.Assertions.assertThat;
    import static play.test.Helpers.fakeApplication;
    import static play.test.Helpers.inMemoryDatabase;
    import static play.test.Helpers.running;
    
    public class ModelTest {
    
        @Test
        public void checkThatIndustriesExist() {
            running(fakeApplication(inMemoryDatabase()), new Runnable() {
                public void run() {
                    Industry industry = new Industry();
                    industry.name = "Some name";
                    industry.shortname = "some-name";
                    industry.save();
                    assertThat(Industry.find.all()).hasSize(1);
                }
            });
        }
    
    }
    

    我的 appication.conf

    application.secret="8aXG0?h`kxccxs6JM?WdB@<v`kwouvQr2<y5Y>9jk3XU1yHV`Yr>18xRKHv8PTdv"
    application.langs="en"
    ebean.default="models.*"
    logger.root=ERROR
    logger.play=INFO
    logger.application=DEBUG
    

    测试输出:

    [stackoverflow-10869508] $ test
    [info] Updating {file:/Users/martin/workspace/stackoverflow-10869508/}stackoverflow-10869508...
    [info] Done updating.                                                                  
    [info] Compiling 4 Scala sources and 3 Java sources to /Users/martin/workspace/stackoverflow-10869508/target/scala-2.9.1/classes...
    [info] Compiling 1 Java source to /Users/martin/workspace/stackoverflow-10869508/target/scala-2.9.1/test-classes...
    [info] models.ModelTest
    [info] + models.ModelTest.checkThatIndustriesExist
    [info] 
    [info] 
    [info] Total for test models.ModelTest
    [info] Finished in 2.289 seconds
    [info] 1 tests, 0 failures, 0 errors
    [info] Passed: : Total 1, Failed 0, Errors 0, Passed 1, Skipped 0
    

    测试输出禁用进化:

    [stackoverflow-10869508] $ test
    [info] Compiling 1 Java source to /Users/martin/workspace/stackoverflow-10869508/target/scala-2.9.1/test-classes...
    [info] models.ModelTest
    [error] Test models.ModelTest.checkThatIndustriesExist failed: Error getting sequence nextval
    [error]     at com.avaje.ebean.config.dbplatform.SequenceIdGenerator.getMoreIds(SequenceIdGenerator.java:213)
    [error]     at com.avaje.ebean.config.dbplatform.SequenceIdGenerator.loadMoreIds(SequenceIdGenerator.java:163)
    [error]     at com.avaje.ebean.config.dbplatform.SequenceIdGenerator.nextId(SequenceIdGenerator.java:118)
    [error]     at com.avaje.ebeaninternal.server.deploy.BeanDescriptor.nextId(BeanDescriptor.java:1218)
    [error]     at com.avaje.ebeaninternal.server.persist.DefaultPersister.setIdGenValue(DefaultPersister.java:1304)
    [error]     at com.avaje.ebeaninternal.server.persist.DefaultPersister.insert(DefaultPersister.java:403)
    [error]     at com.avaje.ebeaninternal.server.persist.DefaultPersister.saveEnhanced(DefaultPersister.java:345)
    [error]     at com.avaje.ebeaninternal.server.persist.DefaultPersister.saveRecurse(DefaultPersister.java:315)
    [error]     at com.avaje.ebeaninternal.server.persist.DefaultPersister.save(DefaultPersister.java:282)
    [error]     at com.avaje.ebeaninternal.server.core.DefaultServer.save(DefaultServer.java:1577)
    [error]     at com.avaje.ebeaninternal.server.core.DefaultServer.save(DefaultServer.java:1567)
    [error]     at com.avaje.ebean.Ebean.save(Ebean.java:538)
    [error]     at play.db.ebean.Model.save(Model.java:76)
    [error]     at models.ModelTest$1.run(ModelTest.java:22)
    [error]     at play.test.Helpers.running(Helpers.java:277)
    [error]     at models.ModelTest.checkThatIndustriesExist(ModelTest.java:17)
    [error]     ...
    [error] Caused by: org.h2.jdbc.JdbcSQLException: Syntax Fehler in SQL Befehl "SELECT INDUSTRY_SEQ.NEXTVAL UNION[*] SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL "; erwartet "identifier"
    [error] Syntax error in SQL statement "SELECT INDUSTRY_SEQ.NEXTVAL UNION[*] SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL UNION SELECT INDUSTRY_SEQ.NEXTVAL "; expected "identifier"; SQL statement:
    [error] select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval union select industry_seq.nextval [42001-158]
    [error]     at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
    [error]     at org.h2.message.DbException.get(DbException.java:169)
    [error]     at org.h2.message.DbException.getSyntaxError(DbException.java:194)
    [error]     at org.h2.command.Parser.readColumnIdentifier(Parser.java:2777)
    [error]     at org.h2.command.Parser.readTermObjectDot(Parser.java:2336)
    [error]     at org.h2.command.Parser.readTerm(Parser.java:2453)
    [error]     at org.h2.command.Parser.readFactor(Parser.java:2035)
    [error]     at org.h2.command.Parser.readSum(Parser.java:2022)
    [error]     at org.h2.command.Parser.readConcat(Parser.java:1995)
    [error]     at org.h2.command.Parser.readCondition(Parser.java:1860)
    [error]     at org.h2.command.Parser.readAnd(Parser.java:1841)
    [error]     at org.h2.command.Parser.readExpression(Parser.java:1833)
    [error]     at org.h2.command.Parser.parseSelectSimpleSelectPart(Parser.java:1746)
    [error]     at org.h2.command.Parser.parseSelectSimple(Parser.java:1778)
    [error]     at org.h2.command.Parser.parseSelectSub(Parser.java:1673)
    [error]     at org.h2.command.Parser.parseSelectUnion(Parser.java:1518)
    [error]     at org.h2.command.Parser.parseSelect(Parser.java:1506)
    [error]     at org.h2.command.Parser.parsePrepared(Parser.java:405)
    [error]     at org.h2.command.Parser.parse(Parser.java:279)
    [error]     at org.h2.command.Parser.parse(Parser.java:251)
    [error]     at org.h2.command.Parser.prepareCommand(Parser.java:217)
    [error]     at org.h2.engine.Session.prepareLocal(Session.java:415)
    [error]     at org.h2.engine.Session.prepareCommand(Session.java:364)
    [error]     at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1119)
    [error]     at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:71)
    [error]     at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:267)
    [error]     at com.jolbox.bonecp.ConnectionHandle.prepareStatement(ConnectionHandle.java:820)
    [error]     at com.avaje.ebean.config.dbplatform.SequenceIdGenerator.getMoreIds(SequenceIdGenerator.java:193)
    [error]     ... 80 more
    [info] x models.ModelTest.checkThatIndustriesExist
    [info] 
    [info] 
    [info] Total for test models.ModelTest
    [info] Finished in 2.028 seconds
    [info] 1 tests, 1 failures, 0 errors
    [error] Failed: : Total 1, Failed 1, Errors 0, Passed 0, Skipped 0
    [error] Failed tests:
    [error]     models.ModelTest
    [error] {file:/Users/martin/workspace/stackoverflow-10869508/}stackoverflow-10869508/test:test: Tests unsuccessful
    [error] Total time: 3 s, completed 03.06.2012 18:34:39
    

    【讨论】:

    • 感谢测试代码!事实上,我发现尚未应用进化(见我的回答)。
    【解决方案3】:

    我的 id 看起来像这样,但我没有收到那个错误...

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long id;
    

    【讨论】:

    • 这个给我修好了,关键是加了@GeneratedValue注解
    猜你喜欢
    • 1970-01-01
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-10
    相关资源
    最近更新 更多