-
-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot create and properly instantiate an eagerly() bound DI component when dependent on Ebean and Evolutions running. #65
Comments
Anyone have any insight on this? |
From what I can tell, after upgrading another application to Play 2.5.3 and play-ebean 3.0.1, this seems fixed. I would like it if someone could independently verify before closing this, but as I have time I will attempt to update my sample project linked above to Play 2.5.3 to see if it is also fixed. |
It seems I also had to inject the following into my module to not have a "Datasource is null?" exception during boot: play.db.ebean.EbeanDynamicEvolutions dynamicEvolutions, |
So it looks like this is still an issue even in Play 2.5.3. I have an eagerly bound module for my application startup and need evolutions to be applied prior to my module constructor running. Injecting DynamicEvolutions and EbeanConfig doesn't seem to be enough for the evolutions to be applied prior to the constructor running in my module. |
Okay, so while this is still a problem for eagerly bound components that need Ebean evolutions to be completed prior to the instantiation of the component, I have found a workaround for now:
The only drawback to this is that it requires a controller to be run for the component to be instantiated. I know this is the intent behind using DI, but it does get in the way of having a headless service (one with no controllers) that may need to rely on a database and using Ebean with evolutions. |
+1 I spend a day troubleshooting this and thought I was going crazy. No matter what I did, Evolutions screwed up schema creations, but had a different effect for me. All submodule's ebean database schemas were mapped to the main project, breaking the ability to migrate and update. |
@justinnichols Were you able to get any luck following the new migration page on compile-time DI with Evolutions? https://www.playframework.com/documentation/2.5.x/ScalaCompileTimeDependencyInjection |
I've not tried that, but I'm also using Java, not Scala. If it translates I may try it, but I've got the above workaround at this time. The biggest problem is that we need a component for Ebean that will guarantee evolutions has run which will allow us to inject in our eagerly instantiated components. To my knowledge no such play-ebean component exists. |
How about this: it's a bit hacky, but I'm also using Java and struggling with the same thing. One of these two options
|
I had thought of that and putting any arbitrary time delay will ultimately fail because the time it takes evolutions to run is not fixed. Imagine adding an index on a table that has millions of records. It takes minutes to run on a fairly fast system. |
If I ever have enough time I may look deep into No matter how much DI tries to do away with bootstraps (assuming that's an intent and not just a byproduct), there are valid cases where it's useful. This is one of those cases if you subscribe to using the runtime to make database changes (which we do). |
I'm starting to think that Evolutions isn't all that useful as a general concept, given how tied in it is to application startup. Especially when there's code generation tools involved -- then you want the database schema created before code generation, and then compilation and application load should happen after that. |
Just to be clarify, I'm pretty sure you are talking about "Play Evolutions" and not "Ebean DB Migrations". If you start looking at Ebean you'll see "create-all" DDL generation (for testing usually), DB Migration generation (DDL diff generation) and DB Migration running (using Flyway or Ebean's own DB Migration runner). Ebean's own DB Migration runner runs the migrations when EbeanServer instance starts just before it becomes available (Refer DefaultServer.run() and DbMigrationConfig.isRunMigration()) ... but understand that this is not Play evolutions. Note: That Ebean's DB Migration runner is actually a separate module that can run by itself (without Ebean, without the application etc) much like how you can run FlywayDB by itself. If Play evolutions is similar then that should be an option. |
Thanks for the response, Rob. My apologies for any confusion, but I looked in the play-ebean code and the only thing I saw it doing was generating a 1.sql (in other words, I didn't see it actually attempt to use the SQL files to run them on the database). Are you saying Ebean is not the responsible party for running the 1.sql, 2.sql, 3.sql...n.sql? If not, then I will instead look into Play evolutions as I must have missed something when I dug into Play's side in the past. |
> only thing I saw it doing was generating a 1.sql Yes. I think Play is getting Ebean to generate the "create-all" script and The point of Ebean DB Migration is to generate (and run) diff's and for *> Are you saying Ebean is not the responsible party for running the 1.sql, Yes, that is what I am saying. Play evolutions is running those which would On 15 June 2016 at 00:29, Justin Nichols notifications@github.com wrote:
|
Of course. I had a brain fart about the play_evolutions. Thanks for the reminder! In this case, I'll update my previous comment to state that I'll dig into what is handling the play_evolutions then. |
I wholeheartedly concur. This situation has been bothering me for weeks. Evolutions has always been temperamental, and actually casued more headaches than it's worth. Right now I'm just programmatically flipping the ebean DDL creation flags, and it seems to be far far more reliable. I looked into Flyway but it's really a different use-case and you'd have to auto create your DDLs anyway, so that's barely worth it. Maybe I'm misunderstanding the two products, but in any case, Evolutions seems poorly supported. I couldn't even find an Evolutions changelog. |
As a hack, I have had success by having an EbeanDynamicEvolutions variable injected into the components that access ebean. I looked through a lot of the classes in the plugin and that one seemed to have the most promise. |
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):
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?
The text was updated successfully, but these errors were encountered: