[Ben L]
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.
Does this mean I can write a Class like:
public class User {
public String username;
}
And play will automatically create a getUsername and a setUsername method (like what Lombok does)?
Yes.
This is gold if it really does that but my small amount of experimentation suggests it doesn't which leads me to the question of what does the above sentence mean?
My quick experimentation and just kept getting the error: Compilation error [cannot find symbol [symbol: method getUsername()] [location: class models.User]]
The generated getters are not available to your java classes, they are generated after the java files are compiled.
But it is even better: In your java classes you don't have to write user.getUsername(), but just user.username and play will rewrite all the java classfile so that field access is turned into calls to the generated getUsername()/setUsername().
This makes both writing the model classes and using them very fluent.
BUT!!!!
1. The rewriting only happens for the generated getters/setters. If you write own getUsername()/setUsername() it will not be called. Then suddenly user.username really access the public field. Yuck.
2. The rewriting only happens on java classes, not on the views, so the views always access the public fields.
Since ORMs also like to rewrite getter/setter to do their own magic, access to the public fields quickly becomes a bad idea.
If we consider encapsulation of our model classes a good idea (we all do, right?) then we are left with only a few options:
1. Put the model classes in a subproject, and use lombok there. The rest of the code can then use getUsername() everywhere.
2. Write your own getter/setter
Do the classes need to be annotated somehow or do they need to extend Model. If they need to extend Model, how does this work for JPA?
There are no requirement for generating getters. Try checking your User class with (user correct packagename):
javap -classpath target/scala-2.9.1/classes models.User
and I'm sure the class have grown a getUsername() and a setUsername().
Any pointers would be appreciated. I have been using Lombok for a long time now and going back to having to write getters/setters is driving me nuts.
Yes indeed.
regards,
Finn