Skip to content
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

Add query bean support #64

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

Conversation

andrewl102
Copy link

resolve #61

val querySettings = Seq(
playEbeanQueryGenerate := false,
playEbeanQueryEnhance := false,
playEbeanQueryDestDirectory := "app",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this should go to SBT's classes_managed directory instead?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it needs to go into a managed source directory, assuming it's a Java file. There's actually a better way to configure directories. Take a look at the Twirl sbt plugin to see how it does it:
https://github.com/playframework/twirl/blob/master/sbt-twirl/src/main/scala/play/twirl/sbt/SbtTwirl.scala.

Concretely here are some steps:

  1. Create a new task called playEbeanQuery. Call this task from ebeanEnhance if playEbeanQueryGenerate is created.
  2. The task should read from sources in playEbeanQuery and output to target in playEbeanQuery.
  3. Add playEbeanQuery task configuration into scopedSettings and define values like sources in playEbeanQuery := resourceDirectory.value and target in playEbeanQuery := crossTarget.value / "ebean-query" / Defaults.nameForSrc(configuration.value.name).
  4. Bind these settings using inConfig(Compile)(scopedSettings) ++ inConfig(Test) ++ ... so it will pick up the different directory values when compiling and testing (see raw and configured settings).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well I'm not sure about that.
Twirl and Query bean generation are two separate things.

When you're writing a twirl template, you only have one canonical source file: the .scala.html that the user actively works with to fulfil their tasks. This is compiled in to a mostly unreadable scala file that is used internally by Play that is then compiled down to an actual class file by the compiler.
In general the user has no interest in the intermediate Scala file so it should be not managed by source control and should be stored in the target folder as it is fine to discard and rebuild the contents of this folder.

This use case is different : if you peruse the example project, you will see that they have simply checked the generated source code into source control and more importantly they have modified the query beans after the initial generation to add additional functionality to them.

If we place it within the managed source directory like this (by default), we are essentially limiting users to only using the autogenerated functionality which is the opposite intent of what I was trying to achieve (based upon the Ebean examples).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andrewl102 can you share a link to the example project you're talking about?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/ebean-orm/avaje-ebeanorm-examples .

The a-basic directory contains an example of usage of query beans.
This is only an example obviously, however it seems quite useful to modify the auto generated finder classes to provide richer functionality.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, sounds like the thing to do then is put the query beans into a managed source directory as Rich suggested. That's how SBT plugins would typically handle this from what I've seen.

We could potentially invoke the code generator twice. Once to generate the never-modified query beans into the managed source directory and once to generate the usually modified Finders into the regular source directory. For simplicity though maybe it's easiest to just generate the query beans and forget about the Finders. The Finders seem rather simple compared to the query beans, so most of the value in the code generation is in generating the query beans, so that seems good enough for a v1 of this feature.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be useful, after reading the previous comments I thought perhaps the way to go was finders -> source control and regular beans -> managed sources.
Ideally this could be done in the same step however it probably requires modification of the existing generation code.

If I ran it twice I'd also have to purge the generated query classes.
I think it's probably worth either making a modification to the other project or just ignoring it as you suggested. The user can always manually copy it to their source control although they'd have to disable the generation afterwards possibly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for simplicity we just don't give the user the ability to generate Finders for now

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've spent some time on this and hit some severe problems.

The query generation code requires the model classes already be compiled. By moving it to a generated source, we now have the condition where we need the sources for the models to be compiled before we trigger the query generation phase.
Even if I manage to bind this at the correct point after the model compilation has taken, it now sets up a scenario where in the person has written code that is dependent on the generated query beans, which will now not compile, preventing the original compilation of the model classes from taking place either if they do a clean compile.

It might be possible to solve this but it's way beyond the difficulty I had originally intended.
I would somehow have to trigger only the compilation of the model classes, without any dependent code, for the purposes of completing this phase with the proposed setup.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for being MIA and not reviewing over the holidays.

That's a good point you bring up. Forget that idea then. Can you add a comment to the code explaining why we're not using managed sources? Don't want someone else trying to go down that path in the future without knowing what they're getting into.

I think if we're not going to use managed sources then this is probably better as a task so that you have to type the task name on the console to trigger it. That way we're not automatically overwriting code you have checked in. Hopefully that will be a much easier change to make.

playEbeanQueryEnhance := false,
playEbeanQueryDestDirectory := "app",
playEbeanQueryResourceDirectory := "conf",
playEbeanQueryModelsPackage := "models",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think users should be able to configure this or the generator must respect models packages even if it is not using the default models package.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be configurable.
If the user specifies playEbeanQueryModelsPackage := "notmodels" in their build.sbt it will override the default models definition unless I'm not understanding your comment correctly.

@benmccann
Copy link
Contributor

@andrewl102 can you squash the commits?

"com.typesafe" % "config" % "1.3.0"
)

def avajeEbeanormAgent = "org.avaje.ebeanorm" % "avaje-ebeanorm-agent" % "4.7.1"
def avajeEbeanormQueryAgent = "org.avaje.ebeanorm" % "avaje-ebeanorm-typequery-agent" % "1.5.1"
def avajeGenerator = "org.avaje.ebeanorm" % "avaje-ebeanorm-typequery-generator" % "1.5.1"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the latest is 1.5.3

@oexza
Copy link

oexza commented Mar 1, 2016

will this make it into play 2.5?

@marcospereira
Copy link
Member

@oexza it don't need to. :-)

The main benefit to have play-ebean as a separated project is that we can release new versions of it independent of Play lifecycle. By independent I mean that we can later release a new version of play-ebean with query bean support without releasing a new version of Play.

@talachutla
Copy link

For java what are the flags

@oexza
Copy link

oexza commented Apr 11, 2016

ping! @andrewl102 @benmccann 😃 is this PR still alive?

@oexza
Copy link

oexza commented Jun 17, 2016

hello guys, still gonna nag you on this @andrewl102 @benmccann @marcospereira where are we at on this Type safety goodness? why is this stalled? is it abandoned?

@rbygrave
Copy link

As a note the Ebean maven artifacts above have since be renamed and updated so:

"org.avaje.ebeanorm" % "avaje-ebeanorm-typequery-agent" % "1.5.1"
"org.avaje.ebeanorm" % "avaje-ebeanorm-typequery-generator" % "1.5.1"

Should ultimately be moved over to:
"org.avaje.ebeanorm" % "querybean-agent" % "2.2.1"
"org.avaje.ebeanorm" % "finder-generator" % "2.1.2"

The "finder-generator" (renamed from avaje-ebeanorm-typequery-generator) ... generates finders but it also generates query beans by reading the entity bean information from compiled classes. I believe this is used because we can't use Java annotation processing.

Ebean's "querybean-generator" artifact is the Java annotation processor that generates query beans (so as I understand it we can't use it at the moment with sbt).

Cheers, Rob.

@benmccann
Copy link
Contributor

benmccann commented Jun 23, 2016

@oexza we stopped working on this due to slight changes in tech stack at Connectifier after being acquired. if you'd like to take over I will be happy to review, but we don't have time to implement ourselves

@aviau
Copy link

aviau commented Feb 20, 2017

I'd love to see this merged. Or is there any way to use query beans without modifications to play-ebeans?

I have managed to get querybeans generation working by just adding "org.avaje.ebean" % "querybean-generator" % "8.1.1" to my dependencies.

Is there a simple way to enable enhancements?

@aprasadh
Copy link

aprasadh commented May 3, 2017

@aviau Hi,

After adding library dependency "org.avaje.ebean" % "querybean-generator" % "8.1.1"

I am getting compiler warnings saying, "...Could not determine source for class models....."

What other dependency you have added to make it work. I am using Play Framework 2.5.14. Part of my build.sbt contains,

val appDependencies = Seq(
  "be.objectify"  %% "deadbolt-java"     % "2.5.0",
  // Comment the next line for local development of the Play Authentication core:
  "com.feth"      %% "play-authenticate" % "0.8.1",
  "org.postgresql"    %  "postgresql"        % "9.4.1212.jre7",
  cache,
  javaWs,
  javaJdbc,
  "org.webjars" % "bootstrap" % "3.2.0",
  "org.easytesting" % "fest-assert" % "1.4" % "test",
  "org.seleniumhq.selenium" % "selenium-java" % "2.52.0" % "test",
  "org.yaml" % "snakeyaml" % "1.18",
  "org.apache.commons" % "commons-lang3" % "3.5",
  "org.avaje.ebean" % "querybean-generator" % "8.1.1"
)

lazy val root = project.in(file("."))
  .enablePlugins(PlayJava, PlayEbean)
  .settings(
    libraryDependencies ++= appDependencies
  )

@AlekseyMko
Copy link

Hi
Is there any chance for this pull request to be merged?
Thank you.

@marcospereira
Copy link
Member

Hey @AlekseyMko, this needs to be revamped given the last updates and changes made in play-ebean. Right now it is not even mergeable since there are conflicts with the current code.

I'm not sure if @andrewl102 still have time to move this forward, but if not, someone can cherry-pick his commits here, solve the conflicts and submit a new pull request. What do you think?

@AlekseyMko
Copy link

Hi @marcospereira. I updated code from this pull request and fixed to make it work. But I did it only for 3.1.1 version of play-ebean plugin. 4.0.0 Uses newer version of ebean and code requires much more changes.
Also I am very new to Play, sbt and Scala and don't understand how does some thing work yet (especially in sbt). I am starting new project with Play stack.

@AlekseyMko
Copy link

I worked a bit with my updated plugin and it couses reloading of application after each request as ebean Generator does not care about changes in models and just regenerates finders and query beans every time. This forces sbt to reload application and makes development process unacceptable.
Possible I will finish this in the future but now I have no time and knowledges in sbt to finish.
I can share my changes if somebody wants to move this forward.

@Flo354
Copy link

Flo354 commented Feb 1, 2019

Any news on that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Typesafe query beans