play-ebean icon indicating copy to clipboard operation
play-ebean copied to clipboard

Evolution can't be run due to "delimiter $$" DDL parsing bug - Play 3, Ebean 8

Open adilaijaz30 opened this issue 1 year ago • 14 comments

We've been using play 2.8.1 with play-ebean 6.0.0 and java 1.8 for years now.

Recently, we decided to upgrade to play 3.0.5, play-ebean 8.3.0 and java 21, but it's been a nightmare due to the play architectural bug which has been ironically unresolved since 2018 (Originally raised: Issue #166 ).

No matter what I do, I can't get rid of the bug.

My question is why the plugin's DDL parser does not properly replace back the "delimiter $$ " to '' and "$$" to a semicolon when it must before executing the SQL?

Like why did you even release the plugin if it can't simply work?

Is there gonna be any solution for this? Let me know, otherwise, I'd have to downgrade back to play 2.8.1.


Config file:

`ebean { default = ["models.global."] local = ["models.local."] }

db{ // datasources of com.mysql.cj.jdbc.Driver }

play.evolutions {

db.default.enabled = true db.default.autoApply = true

db.local.enabled = true db.local.autoApply = true } `


build.sbt

` lazy val root = (project in file(".")).enablePlugins(PlayJava, PlayEbean)

libraryDependencies ++= Seq( guice, ws, jdbc, javaJdbc )

playEbeanModels in Compile := Seq("models.global.", "models.local.") `


Issue

Image


Solutions tried:

I tried a lot of solutions like setting ebean.ddl.generate and run in config file as well as settings values of ebean.migration.xxx, but always gave me "ddl is type OBJECT rather than LIST" etc etc.

I also tried importing io.ebean agents, ddl-generator, ddl-parser and a lot of different stuff.

I also tried using ebean-platform.

I also tried "-Debean.ddl.generateProcedures=false" in javacOptions.

I also tried creating a custom evolution parser to somehow run it after creating SQL and before executing SQL to replace the 'delimiter $$' issues.

P.s. I'm only seeking an automatic solution (and not manually removing the separators by hand.)

adilaijaz30 avatar Nov 12 '24 17:11 adilaijaz30

And I think I don't even require procedures.

and there seems to be no way to turn off generating procedures

adilaijaz30 avatar Nov 13 '24 09:11 adilaijaz30

I also tried "-Debean.ddl.generateProcedures=false" in javacOptions.

This will not work. First its not a compiler option. Second you need to set it on the jvm instance that is running ebean, which in dev mode (where the jvm does not get forked), is the same jvm which runs sbt. To pass the flag to the jvm in dev mode create a file .jvmopts in your project's root folder with the content:

-Debean.ddl.generateProcedures=false

mkurz avatar Nov 13 '24 09:11 mkurz

Also since 8.1.0 you can disable the generation of the evolutions scripts (in app conf):

play.ebean.generateEvolutionsScripts = false

mkurz avatar Nov 13 '24 09:11 mkurz

I can’t turn off generating the evolution scripts, because I can’t write SQLs for like 20 schemas.

I want play-ebean to generate and execute them for me.

adilaijaz30 avatar Nov 13 '24 10:11 adilaijaz30

Is there any proper solution of this bug apart from turning off generating procedures (which is unclear what exactly to do as I don’t have much knowledge about jvm options)

adilaijaz30 avatar Nov 13 '24 10:11 adilaijaz30

You say you have an existing application that you migrate, so i think you already have evolution files? Just 1 or more? Or what, with Play 2.8 is your current workflow? Like if you have this application in production, you probably always add to add new evolution files when you update the schema or not?

mkurz avatar Nov 13 '24 10:11 mkurz

On development, we used to get new evolution files generated and applied automatically whenever there's a change in one or more entities. This was because we have:


play.evolutions {

  db.default.enabled = true
  db.local.enabled = true
  
  db.default.autoApply = true
  db.local.autoApply = true
}

On production, we go to MySql workbench to update the schema manually if there's a change in it.

adilaijaz30 avatar Nov 13 '24 10:11 adilaijaz30

we used to get new evolution files generated

How? Like if you already have lets say 7 evolution files, was the 8th generated automatically? How? Who did generate that file?

mkurz avatar Nov 13 '24 10:11 mkurz

play-ebean generates/replaces the evolution files in

"/evolutions/default/1.sql" "/evolutions/local/1.sql"

so it's always one SQL file that's regenerated by play-ebean. We are not used to even touching those SQL files.

adilaijaz30 avatar Nov 13 '24 11:11 adilaijaz30

OK I get it. I try to figure something out.

mkurz avatar Nov 13 '24 11:11 mkurz

btw, if I add -Debean.ddl.generateProcedures=false to .jvmopts file. I get the error "ddl has type OBJECT rather than LIST"

Image

adilaijaz30 avatar Nov 13 '24 11:11 adilaijaz30

Opened

  • https://github.com/playframework/playframework/issues/12968

Let's see if we can convince the ebean author to help out here a bit.

mkurz avatar Nov 13 '24 12:11 mkurz

btw, if I add -Debean.ddl.generateProcedures=false to .jvmopts file. I get the error "ddl has type OBJECT rather than LIST"

Please open a separate issue in this repo for that. Thanks!

mkurz avatar Nov 13 '24 12:11 mkurz

I think the simplest solution is to parse the sql script returned by ebean and convert it to play evolutions compatible sql. It's not the nicest solution, but it will work.

https://github.com/playframework/play-ebean/blob/a2bf5304b0739a56abcdbe0cefdc2dc1484a5465/play-ebean/src/main/java/play/db/ebean/EbeanDynamicEvolutions.java#L74-L74

mkurz avatar Nov 26 '24 09:11 mkurz