#799 ✓resolved
Kristian Lein-Mathisen

"Please annotate your JPA model with @javax.persistence.Entity annotation" when @Entity is present

Reported by Kristian Lein-Mathisen | May 4th, 2011 @ 01:57 PM | in 1.2.4 (closed)

Framework version: 1.1.1
Platform you're using: Linux, Ubuntu 10.04

Reproduction steps:

Download my attached test-project and do:

$ echo "prod" | play id $ play run

An exception is thrown from the OnApplicationStart job, but is also thrown from controllers when you try to do StoredSmsIn.findAll();

If you do

$ echo "" | play id $ play run

It all seems to work. So my suggestion is that something's wrong with the precompilation-phase.

Details:

The problem seems to be unrelated to database setup, but rather something to do with the compilation-phase.

Comments and changes to this ticket

  • Lauri Kimmel

    Lauri Kimmel May 4th, 2011 @ 10:11 PM

    Same exception is thrown when running unit tests which are using model classes annotated with @Entity in Eclipse:

    java.lang.UnsupportedOperationException: Please annotate your JPA model with @javax.persistence.Entity annotation.
        at play.db.jpa.GenericModel.count(GenericModel.java:232)
        at models.SimpleEntityTest.testCount(SimpleEntityTest.java:17)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        ...
    

    Framework version: 1.2, 1.2.1

    Reproduction steps:

    • download attached project
    • unzip
    • run play eclipsify
    • import to Eclipse workspace
    • select Run As -> JUnit Test on project's test folder

    Details:
    Same test is successful when running via play auto-test.

    Similar problems with Morphia Entities. See this thread for more info.

  • Kristian Lein-Mathisen

    Kristian Lein-Mathisen June 9th, 2011 @ 09:56 AM

    The problem is still present in Play 1.2.1:

    I unzip the file from my first post and do play run (id is empty so it goes to dev mode). localhost:9000 starts the app.

    I do

    $ echo "prod" | play id
    $ play run
    

    And it still gives me the "Please annotate your Entities" exection:

    @66kni24ed
    Error during job execution (jobs.InitDatabase)
    
    Execution exception (In /app/jobs/InitDatabase.java around line 27)
    UnsupportedOperationException occured : Please annotate your JPA model with @javax.persistence.Entity annotation.
    
    play.exceptions.JavaExecutionException: Please annotate your JPA model with @javax.persistence.Entity annotation.
        at play.jobs.Job.call(Job.java:166)
        at Invocation.Job(Play!)
    Caused by: java.lang.UnsupportedOperationException: Please annotate your JPA model with @javax.persistence.Entity annotation.
        at play.db.jpa.GenericModel.findAll(GenericModel.java:250)
        at jobs.InitDatabase.loadDatabase(InitDatabase.java:27)
        at jobs.InitDatabase.doJob(InitDatabase.java:15)
        at play.jobs.Job.doJobWithResult(Job.java:55)
        at play.jobs.Job.call(Job.java:157)
        ... 1 more
    Exception in thread "main" play.exceptions.JavaExecutionException: Please annotate your JPA model with @javax.persistence.Entity annotation.
        at play.jobs.Job.call(Job.java:166)
        at Invocation.Job(Play!)
    Caused by: java.lang.UnsupportedOperationException: Please annotate your JPA model with @javax.persistence.Entity annotation.
        at play.db.jpa.GenericModel.findAll(GenericModel.java:250)
        at jobs.InitDatabase.loadDatabase(InitDatabase.java:27)
        at jobs.InitDatabase.doJob(InitDatabase.java:15)
        at play.jobs.Job.doJobWithResult(Job.java:55)
        at play.jobs.Job.call(Job.java:157)
        ... 1 more
    

    I'm on Ubuntu with sun-java:

    $ java -version
    java version "1.6.0_24"
    Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
    Java HotSpot(TM) 64-Bit Server VM (build 19.1-b02, mixed mode)
    
  • Erik Bakker

    Erik Bakker June 9th, 2011 @ 02:11 PM

    I run into this problem as well, with Play! 1.2.1.

  • Morten Kjetland

    Morten Kjetland June 17th, 2011 @ 12:53 PM

    • Milestone set to 1.3
    • State changed from “new” to “confirmed”
    • Assigned user set to “Morten Kjetland”
    • Milestone order changed from “535” to “0”
  • Morten Kjetland

    Morten Kjetland June 17th, 2011 @ 01:04 PM

    The problem is this:

    Jobs annotated with @OnApplicationStart is executed "outside" the regular job-execution handling. This means that all the "prepare jpa"-stuff is not happening before it is executed.

    But, when running in dev mode, play is started when the first request is received -> play is started from the thread processing this first request -> JPA-stuff is inited for the request -> so when the @OnApplicationStart-job is executed in dev mode all jpa suff is inited..

    I'll look into how to fix this problem

  • Erik Bakker

    Erik Bakker June 17th, 2011 @ 04:21 PM

    Are you sure? For me, the problem does not occur in a job, but during a regular request:

    
    @66n5l3aji
    Internal Server Error (500) for request GET /
    
    Execution exception (In /app/models/User.java around line 423)
    UnsupportedOperationException occured : Please annotate your JPA model with @javax.persistence.Entity annotation.
    
    play.exceptions.JavaExecutionException: Please annotate your JPA model with @javax.persistence.Entity annotation.
            at play.mvc.ActionInvoker.invoke(ActionInvoker.java:227)
            at Invocation.HTTP Request(Play!)
    Caused by: java.lang.UnsupportedOperationException: Please annotate your JPA model with @javax.persistence.Entity annotation.
            at play.db.jpa.GenericModel.find(GenericModel.java:269)
            at models.User.getUpcomingBookings(User.java:423)
            at models.User.getNotifications(User.java:515)
            at controllers.Base.addSidebarContent(Base.java:131)
            at play.mvc.ActionInvoker.invoke(ActionInvoker.java:500)
            at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:474)
            at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:469)
            at play.mvc.ActionInvoker.handleBefores(ActionInvoker.java:318)
            at play.mvc.ActionInvoker.invoke(ActionInvoker.java:138)
            ... 1 more
    

    Unfortunately I don't have a minimal example handy. I'll see if I can make one.

  • Morten Kjetland

    Morten Kjetland June 17th, 2011 @ 07:51 PM

    Erik Bakker: Do you get that error all the time or only some times? If it is not related to @OnApplicationStart, please open a new ticket and attach info about how to reproduce it.

  • Morten Kjetland

    Morten Kjetland June 17th, 2011 @ 08:48 PM

    My first explanation of the error was wrong:

    This is what happens:

    (I have not fully understod it yet)

    in dev mode all internal plugins are loaded up front, so when the first app-class is loaded all plugins are ready to enhance the class.

    in prod mode, when play loads plugins, the user-plugin supplied in the test-project is also loaded.
    Since this plugin uses/referes to some of the model-classes they are loaded also.. when these models are loaded they are immediately enhanched, but this happens before all the core-plugins are loaded. This results in not all plugins (ie the JPAPlugin) being able to enhance the model-classes.

    I'm investigating how to fix this.

  • Play Duck

    Play Duck June 17th, 2011 @ 10:12 PM

    (from [48c213caef37c4288bac452104e22bd676fc557d]) [#799] Fixes running multiple tests in eclipse/intellij by always loading test-class through plays classloader https://github.com/playframework/play/commit/48c213caef37c4288bac45...

  • Play Duck
  • Morten Kjetland

    Morten Kjetland June 17th, 2011 @ 10:14 PM

    • State changed from “confirmed” to “resolved”

    fixed two different bugs:

    By always loading loading plays internal plugins first, we fix the missing enhanche problem

    JUnit runner will now always make sure the test class (and all classes it uses) is loaded through play classloader.
    Before this fix, only the (first) test-class that triggered play to start was properly loaded

  • Erik Bakker

    Erik Bakker June 18th, 2011 @ 10:13 AM

    Hi Morten, I agree with your analysis of the problem.

    However, are you sure that loading the internal plugins first is the right solution? The play.plugins file defines an explicit importance / order for every plugin (the first number in each line). I think thát should be the order in which the plugins are loaded as well, and not whether they are internal or not. I could for example imagine wanting a custom plugin to be loaded before the internal plugins :)

    What are your thoughts about this?

  • Morten Kjetland

    Morten Kjetland June 18th, 2011 @ 12:08 PM

    The fix only affect the order the plugin classes are loaded. They are still
    executed in the correct order.

  • Erik Bakker

    Erik Bakker June 18th, 2011 @ 12:42 PM

    Excellent, thanks for the clarification :)

  • Erik Bakker

    Erik Bakker June 20th, 2011 @ 10:17 AM

    This issue is not resolved. See the attached minimal example, which breaks using the current Github master branch, which includes Mortens patches.

    What seems to happen is that the play.plugins file that defines my own plugin, is also seen by the parent class loader. So even with lookInParentClassloaderFirst = true in ApplicationClassloader.getResources, it is returned befóre the core play.plugins file from the framework jar and the loading of my plugin causes model classes to be loaded before the JPA plugin is loaded.

    How to use the example:

    • Run the application in production mode (play run --%prod)
    • Open /
    • Observe the error notice in your browser, and the generated stack trace in the console
  • Morten Kjetland

    Morten Kjetland June 20th, 2011 @ 10:25 AM

    • State changed from “resolved” to “confirmed”

    I tried your new test-project and it fails over here too..

  • Morten Kjetland

    Morten Kjetland June 20th, 2011 @ 10:44 AM

    If you move the play.plugin file to the app folder it works.

    the problem is that the conf folder is added to the jvm classloader-path when starting play to make log4j.properties visible to log4j.

    we should probably, in the plugin loading code, assert that the app does not have play.plugin file in conf folder

  • Erik Bakker

    Erik Bakker June 20th, 2011 @ 11:30 AM

    Hmm, but moving what seems to be a configuration file out of /conf for technical reasons seems a bit fishy...

    But there is an underlying cause here. Loading the plugins out-of-order is only a problem when a plugin load causes a load of another application class, such as a model. These circumstances seem to be rare; I managed to reproduce one in my example; a method invocation with a subclass of a class in the method signature seems to cause loading of both the class in the method signature (Model in the example) and the actual class (TestModel in the example).

    Wouldn't the problem be more neatly solved if we load all the plugin classes first, and then reload all the classes that were loaded as a result of this, so that all the plugins get the chance to enhance all these classes?

    Because this bug could also happen with two non-core plugins that both want to enhance a class. If the loading of the first plugin causes a Model class to be loaded, the second plugin will never be able to enhance it, and the current fix will not work either.

    BTW, I generated a stacktrace at the point where TestModel was loaded:

    java.lang.Exception: Stack trace
            at java.lang.Thread.dumpStack(Thread.java:1249)
            at play.classloading.ApplicationClassloader.loadClass(ApplicationClassloader.java:85)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
            at java.lang.Class.getDeclaredConstructors0(Native Method)
            at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)
            at java.lang.Class.getConstructor0(Class.java:2699)
            at java.lang.Class.newInstance0(Class.java:326)
            at java.lang.Class.newInstance(Class.java:308)
            at play.plugins.PluginCollection.loadPlugins(PluginCollection.java:100)
            at play.Play.init(Play.java:273)
            at play.server.Server.main(Server.java:141)
    

    So when TestPlugin is loaded, the java.lang.Class.newInstance causes TestModel and Model to be loaded.

  • Morten Kjetland

    Morten Kjetland June 20th, 2011 @ 11:39 AM

    The reloading all classes won't work: when the plugin class was loaded it got its reference to the model-classes - a reload won't fix that.
    then you have to reload all the plugins again - and history repeats it self.

    one other solution is to parse all play.plugin files first without loading anything. then sort them based on index, then load them in that order. Then a plugin has to make sure it's index is after other plugins which it needs when loading its classes.

  • Erik Bakker

    Erik Bakker June 20th, 2011 @ 11:46 AM

    I think that last suggestion is the best solution.

  • Play Duck

    Play Duck June 20th, 2011 @ 10:56 PM

    (from [de581337081fbd7e231841c044ab491271000528]) [#799] Better fix for plugin/enhancing problem: Loads all play.plugin-files, sort plugins by index, then load plugin-classes in correct order reverts this commit: 67ee20bbaf6a649b01d0
    https://github.com/playframework/play/commit/de581337081fbd7e231841...

  • Morten Kjetland

    Morten Kjetland June 20th, 2011 @ 10:57 PM

    • State changed from “confirmed” to “resolved”
  • Morten Kjetland

    Morten Kjetland September 21st, 2011 @ 09:35 PM

    • Tag set to candidate124
  • Play Duck

    Play Duck September 22nd, 2011 @ 07:37 PM

    (from [c192ff19c700b839be4cb84c3d188ca1eb000166]) [#799] Fixes running multiple tests in eclipse/intellij by always loading test-class through plays classloader https://github.com/playframework/play/commit/c192ff19c700b839be4cb8...

  • Play Duck

    Play Duck September 22nd, 2011 @ 07:37 PM

    (from [45949fbc692b180b5f89cbd79027602c8474fa90]) [#799] Better fix for plugin/enhancing problem: Loads all play.plugin-files, sort plugins by index, then load plugin-classes in correct order reverts this commit: 67ee20bbaf6a649b01d0
    https://github.com/playframework/play/commit/45949fbc692b180b5f89cb...

  • Play Duck
  • Morten Kjetland

    Morten Kjetland September 22nd, 2011 @ 07:37 PM

    • Milestone changed from 1.3 to 1.2.4
    • Tag cleared.
    • Milestone order changed from “19” to “0”

    merged into 1.2.x

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2>Play framework</h2>

Play makes it easier to build Web applications with Java. It is a clean alternative to bloated Enterprise Java stacks. It focuses on developer productivity and targets RESTful architectures. Learn more on the <a href="http://www.playframework.org">http://www.playframework.org</a> website.<br><br>

<h2>Source code is hosted on github</h2>Check out our repository at <a href="http://github.com/playframework/play">http://github.com/playframework/play</a><br><br>

<h2>Contributing, creating a patch</h2> Please read the <a href="http://play.lighthouseapp.com/projects/57987/contributor-guide">contributor guide</a><br><br>

<h2>Reporting Security Vulnerabilities</h2> Since all bug reports are public, please report any security vulnerability directly to <em>guillaume dot bort at gmail dot com</em>.<br><br>

<h2>Creating a bug report</h2> Bug reports are incredibly helpful, so take time to report bugs and request features in our ticket tracker. We’re always grateful for patches to Play’s code. Indeed, bug reports with attached patches will get fixed far quickly than those without any.<br><br>

Please include as much relevant information as possible including the exact framework version you're using and a code snippet that reproduces the problem.<br><br>

Don't have too much expectations. Unless the bug is really a serious "everything is broken" thing, you're creating a ticket to start a discussion. Having a patch (or a branch on Github we can pull from) is better, but then again we'll only pull high quality branches that make sense to be in the core of Play.