Skip to content

Cannot create and properly instantiate an eagerly() bound DI component when dependent on Ebean and Evolutions running. #65

@justinnichols

Description

@justinnichols

Here is what is happening and maybe I can get some guidance on this. I have read through and tried what was suggested in #51 without any solution.

I created a github project to demonstrate the issue. It is here: https://github.com/justinnichols/broken-play-ebean-di

EDIT>> I have migrated away from using Github. I now have the project here: https://gitlab.com/justinnichols/broken-play-ebean-di

The crux of the problem is that when using Ebean dynamic evolutions, the DI module, when eagerly() started, may or may not be attempted to be instantiated after the evolutions take place. It causes the following issue when starting (randomly, sometimes it works, sometimes it doesn't):

$ activator run
[info] Loading project definition from /home/justin/src/github/justinnichols/broken-play-ebean-di/project
[info] Set current project to broken-play-ebean-di (in build file:/home/justin/src/github/justinnichols/broken-play-ebean-di/)

--- (Running the application, auto-reloading is enabled) ---

[info] p.c.s.NettyServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000

(Server started, use Ctrl+D to stop and go back to the console...)

[info] - application - Creating Pool for datasource 'default'
[info] - play.api.db.DefaultDBApi - Database [default] connected at jdbc:mysql://localhost/testdb?useUnicode=yes&characterEncoding=UTF-8&connectionCollation=utf8_general_ci
[error] - application - 

! @6o6pp4o27 - Internal server error, for (GET) [/] ->

play.api.UnexpectedException: Unexpected exception[CreationException: Unable to create injector, see the following errors:

1) Error injecting constructor, javax.persistence.PersistenceException: ERROR executing DML bindLog[] error[Table 'testdb.log' doesn't exist]
  at components.BrokenPlayEbeanDIComponentImpl.<init>(BrokenPlayEbeanDIComponentImpl.java:15)
  at components.BrokenPlayEbeanDIComponentImpl.class(BrokenPlayEbeanDIComponentImpl.java:15)
  while locating components.BrokenPlayEbeanDIComponentImpl
  at modules.BrokenPlayEbeanDIModule.bindings(BrokenPlayEbeanDIModule.java:17):
Binding(interface components.BrokenPlayEbeanDIComponent to ConstructionTarget(class components.BrokenPlayEbeanDIComponentImpl) eagerly) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
  while locating components.BrokenPlayEbeanDIComponent

1 error]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:165) ~[play-server_2.11-2.4.3.jar:2.4.3]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:121) ~[play-server_2.11-2.4.3.jar:2.4.3]
    at scala.Option.map(Option.scala:146) ~[scala-library-2.11.7.jar:na]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1.apply(DevServerStart.scala:121) ~[play-server_2.11-2.4.3.jar:2.4.3]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1.apply(DevServerStart.scala:119) ~[play-server_2.11-2.4.3.jar:2.4.3]
    at scala.util.Success.flatMap(Try.scala:231) ~[scala-library-2.11.7.jar:na]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:119) ~[play-server_2.11-2.4.3.jar:2.4.3]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:111) ~[play-server_2.11-2.4.3.jar:2.4.3]
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24) ~[scala-library-2.11.7.jar:na]
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24) ~[scala-library-2.11.7.jar:na]
    at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402) ~[na:1.8.0_66]
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) ~[na:1.8.0_66]
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056) ~[na:1.8.0_66]
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692) ~[na:1.8.0_66]
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157) ~[na:1.8.0_66]
Caused by: com.google.inject.CreationException: Unable to create injector, see the following errors:

1) Error injecting constructor, javax.persistence.PersistenceException: ERROR executing DML bindLog[] error[Table 'testdb.log' doesn't exist]
  at components.BrokenPlayEbeanDIComponentImpl.<init>(BrokenPlayEbeanDIComponentImpl.java:15)
  at components.BrokenPlayEbeanDIComponentImpl.class(BrokenPlayEbeanDIComponentImpl.java:15)
  while locating components.BrokenPlayEbeanDIComponentImpl
  at modules.BrokenPlayEbeanDIModule.bindings(BrokenPlayEbeanDIModule.java:17):
Binding(interface components.BrokenPlayEbeanDIComponent to ConstructionTarget(class components.BrokenPlayEbeanDIComponentImpl) eagerly) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
  while locating components.BrokenPlayEbeanDIComponent

1 error
    at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:466) ~[guice.jar:na]
    at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:184) ~[guice.jar:na]
    at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:110) ~[guice.jar:na]
    at com.google.inject.Guice.createInjector(Guice.java:96) ~[guice.jar:na]
    at com.google.inject.Guice.createInjector(Guice.java:73) ~[guice.jar:na]
    at com.google.inject.Guice.createInjector(Guice.java:62) ~[guice.jar:na]
    at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:126) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:93) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1$$anonfun$2.apply(DevServerStart.scala:153) ~[play-server_2.11-2.4.3.jar:2.4.3]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1$$anonfun$2.apply(DevServerStart.scala:150) ~[play-server_2.11-2.4.3.jar:2.4.3]
    at play.utils.Threads$.withContextClassLoader(Threads.scala:21) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:150) ~[play-server_2.11-2.4.3.jar:2.4.3]
    ... 14 common frames omitted
Caused by: javax.persistence.PersistenceException: ERROR executing DML bindLog[] error[Table 'testdb.log' doesn't exist]
    at com.avaje.ebeaninternal.server.persist.dml.DmlBeanPersister.execute(DmlBeanPersister.java:90) ~[avaje-ebeanorm-4.6.2.jar:na]
    at com.avaje.ebeaninternal.server.persist.dml.DmlBeanPersister.insert(DmlBeanPersister.java:57) ~[avaje-ebeanorm-4.6.2.jar:na]
    at com.avaje.ebeaninternal.server.persist.DefaultPersistExecute.executeInsertBean(DefaultPersistExecute.java:59) ~[avaje-ebeanorm-4.6.2.jar:na]
    at com.avaje.ebeaninternal.server.core.PersistRequestBean.executeNow(PersistRequestBean.java:446) ~[avaje-ebeanorm-4.6.2.jar:na]
    at com.avaje.ebeaninternal.server.core.PersistRequestBean.executeOrQueue(PersistRequestBean.java:480) ~[avaje-ebeanorm-4.6.2.jar:na]
    at com.avaje.ebeaninternal.server.persist.DefaultPersister.insert(DefaultPersister.java:261) ~[avaje-ebeanorm-4.6.2.jar:na]
    at com.avaje.ebeaninternal.server.persist.DefaultPersister.insert(DefaultPersister.java:211) ~[avaje-ebeanorm-4.6.2.jar:na]
    at com.avaje.ebeaninternal.server.persist.DefaultPersister.save(DefaultPersister.java:199) ~[avaje-ebeanorm-4.6.2.jar:na]
    at com.avaje.ebeaninternal.server.core.DefaultServer.save(DefaultServer.java:1461) ~[avaje-ebeanorm-4.6.2.jar:na]
    at com.avaje.ebeaninternal.server.core.DefaultServer.save(DefaultServer.java:1454) ~[avaje-ebeanorm-4.6.2.jar:na]
    at dao.LogDaoImpl.create(LogDaoImpl.java:26) ~[na:na]
    at components.BrokenPlayEbeanDIComponentImpl.<init>(BrokenPlayEbeanDIComponentImpl.java:16) ~[na:na]
    at components.BrokenPlayEbeanDIComponentImpl$$FastClassByGuice$$1a98aa44.newInstance(<generated>) ~[na:na]
    at com.google.inject.internal.cglib.reflect.$FastConstructor.newInstance(FastConstructor.java:40) ~[guice.jar:na]
    at com.google.inject.internal.DefaultConstructionProxyFactory$1.newInstance(DefaultConstructionProxyFactory.java:61) ~[guice.jar:na]
    at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:105) ~[guice.jar:na]
    at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:85) ~[guice.jar:na]
    at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:267) ~[guice.jar:na]
    at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46) ~[guice.jar:na]
    at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1103) ~[guice.jar:na]
    at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40) ~[guice.jar:na]
    at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:145) ~[guice.jar:na]
    at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:41) ~[guice.jar:na]
    at com.google.inject.internal.FactoryProxy.get(FactoryProxy.java:56) ~[guice.jar:na]
    at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46) ~[guice.jar:na]
    at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1103) ~[guice.jar:na]
    at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40) ~[guice.jar:na]
    at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:145) ~[guice.jar:na]
    at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:41) ~[guice.jar:na]
    at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:205) ~[guice.jar:na]
    at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:199) ~[guice.jar:na]
    at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1092) ~[guice.jar:na]
    at com.google.inject.internal.InternalInjectorCreator.loadEagerSingletons(InternalInjectorCreator.java:199) ~[guice.jar:na]
    at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:180) ~[guice.jar:na]
    ... 25 common frames omitted
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'testdb.log' doesn't exist
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_66]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_66]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_66]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422) ~[na:1.8.0_66]
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:400) ~[mysql-connector-java-5.1.36.jar:5.1.36]
    at com.mysql.jdbc.Util.getInstance(Util.java:383) ~[mysql-connector-java-5.1.36.jar:5.1.36]
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:980) ~[mysql-connector-java-5.1.36.jar:5.1.36]
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3847) ~[mysql-connector-java-5.1.36.jar:5.1.36]
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3783) ~[mysql-connector-java-5.1.36.jar:5.1.36]
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2447) ~[mysql-connector-java-5.1.36.jar:5.1.36]
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2594) ~[mysql-connector-java-5.1.36.jar:5.1.36]
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2545) ~[mysql-connector-java-5.1.36.jar:5.1.36]
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1901) ~[mysql-connector-java-5.1.36.jar:5.1.36]
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2113) ~[mysql-connector-java-5.1.36.jar:5.1.36]
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2049) ~[mysql-connector-java-5.1.36.jar:5.1.36]
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2034) ~[mysql-connector-java-5.1.36.jar:5.1.36]
    at com.zaxxer.hikari.proxy.PreparedStatementProxy.executeUpdate(PreparedStatementProxy.java:61) ~[HikariCP.jar:na]
    at com.zaxxer.hikari.proxy.PreparedStatementJavassistProxy.executeUpdate(PreparedStatementJavassistProxy.java) ~[HikariCP.jar:na]
    at com.avaje.ebeaninternal.server.type.DataBind.executeUpdate(DataBind.java:56) ~[avaje-ebeanorm-4.6.2.jar:na]
    at com.avaje.ebeaninternal.server.persist.dml.InsertHandler.execute(InsertHandler.java:128) ~[avaje-ebeanorm-4.6.2.jar:na]
    at com.avaje.ebeaninternal.server.persist.dml.DmlBeanPersister.execute(DmlBeanPersister.java:80) ~[avaje-ebeanorm-4.6.2.jar:na]
    ... 58 common frames omitted

Notice the Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'testdb.log' doesn't exist

If I immediately re-run the application, it works perfectly (because that table now exists).

Please if at all possible, can I get some guidance on how to make it work so that I can use Ebean in an eagerly() instantiated component with evolutions turned on?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions