Search code examples
javascalaplayframework-2.2

Play framework 2.2.0 doesn't generate getter/setter automatically


While tacking Play framework, I've found really annoying situation that I had to spend much time to point out where is root of evil!

To simplify the situation let's consider the code below :

In controllers.Application.java :

return ok(views.html.method1.render(Person.find.all());

In method1.scala.html :

@(people : List[Person])
...
@for(person <- people) {
     @person.name
     @person.pet.getName()
     @person.pet.name
}

In Person.java :

@Id
public Long id;
@ManyToOne
public Pet name;
...

The problem is when I manually set getName() method inside of Pet class. The value is returned. But when I let to be generated automatically by Play framework, it doesn't return any value!

Certainly Play framework has generated getters for person which I can access by person.name.

It's not supposed to be generated automatically ?


Solution

  • http://www.playframework.com/documentation/2.2.x/JavaEbean states that getters and setters are generated at runtime (for plain old Java libraries that require them) and won't be visible at compile time:

    Play has been designed to generate getter/setter automatically, to ensure compatibility with libraries that expect them to be available at runtime (ORM, Databinder, JSON Binder, etc). If Play detects any user-written getter/setter in the Model, it will not generate getter/setter in order to avoid any conflict.

    Caveats:

    (1) Because Ebean class enhancement occurs after compilation, do not expect Ebean-generated getter/setters to be available at compilation time. If you’d prefer to code with them directly, either add the getter/setters explicitly yourself, or ensure that your model classes are compiled before the remainder of your project, eg. by putting them in a separate subproject.

    (2) Enhancement of direct Ebean field access (enabling lazy loading) is only applied to Java classes, not to Scala. Thus, direct field access from Scala source files (including standard Play templates) does not invoke lazy loading, often resulting in empty (unpopulated) entity fields. To ensure the fields get populated, either (a) manually create getter/setters and call them instead, or (b) ensure the entity is fully populated before accessing the fields.

    Therefore the getter isn't visible in your template. If you need lazy loading (see 2)) I suggest you let your getters and setters generate by your IDE. If you don't need lazy loading, just access the fields, they are public anyway.

    BTW: a reference in class Person to class Pet named name sounds like an awkward data model, no offense.