Default/parameterless constructor for Models

150 views
Skip to first unread message

James Gregory

unread,
Sep 19, 2011, 2:06:49 PM9/19/11
to play-fr...@googlegroups.com
Play! doesn't seem to need a parameterless constructor defined on your Model classes. No exceptions are thrown and everything seems to work fine. However, when a class which doesn't have a parameterless constructor is instantiated when doing Fixtures.load, no inline intialization of fields happen.

For example:

public class MyEntity extends Model {
  String name;
  List<String> history = new ArrayList<String>();

  public MyEntity(String name) {
    this.name = name;
  }

  @PrePersist
  void created() {
    history.add("Created");
  }
}

If I do new MyEntity("test").save(), everything works fine; however, when an entity is loaded from a fixture, an exception is thrown at history.add because for some reason history is uninitialised. If I add a default constructor, history is correctly initialised.

This seems like a bug to me, what do you think?

If a default constructor is required, I would expect an exception to be thrown telling me so... if one isn't technically required, then I would expect field initialization to work.

I don't mind adding a default constructor, which is what I'll do, but this does seem like a bit of a grey area.

Thanks

green

unread,
Sep 19, 2011, 7:13:07 PM9/19/11
to play-fr...@googlegroups.com
I think the problem of Fixtures.load is it use Class.newInstance() to create new instance of your model, which will bypass the constructor (which, in turn, will initialize the field). Therefore the solution could be:
  
  void history() {
    if (null == history) history = new ArrayList<String>();
  }
  @PrePersist
  void created() {
    history().add("Created");
  }

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To view this discussion on the web visit https://groups.google.com/d/msg/play-framework/-/SNkqB50p49QJ.
To post to this group, send email to play-fr...@googlegroups.com.
To unsubscribe from this group, send email to play-framewor...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/play-framework?hl=en.

James Gregory

unread,
Sep 20, 2011, 5:23:29 AM9/20/11
to play-fr...@googlegroups.com
That makes sense. Is there any way Fixtures.load could be modified to not bypass the constructor? Either that, or throw an exception. The current behaviour is a bit concerning.

Fixtures.load will use the default constructor if it's available. But obviously, if you define a class with a specialised constructor Java won't generate the implicit default. Could Fixtures.load throw at this point instead of kind-of working in a slightly dangerous way. Either that, or could Fixtures.load be made smarter, and use whatever constructor is available. Speculation, I know. Once I become more familiar with things, this might be something I could do and submit a pull request. If it's something people think is important.

The work arounds are easy enough, and that's what I'm doing presently (either what you suggest, or just putting a default constructor in place).

Pascal Voitot Dev

unread,
Sep 20, 2011, 5:40:09 AM9/20/11
to play-fr...@googlegroups.com
I thought Play searched the default constructor and tried a Class.newInstance() if not found.
The fact is that Play can't really know that you defined specialized constructors and which one should be used in the given case...

I agree it could throw an exception because the more I think about, the more Class.newInstance is really not good :) (we have the same kind of questions in siena/crudsiena)

Pascal

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To view this discussion on the web visit https://groups.google.com/d/msg/play-framework/-/4iX0z43PGLkJ.

James Gregory

unread,
Sep 20, 2011, 5:47:41 AM9/20/11
to play-fr...@googlegroups.com
Yeah, deciding which constructor to use if there isn't a default one is probably a bit of a rabbit hole. I know IoC containers tend to pick the constructor with the most parameters and try to satisfy that... but to be honest, that's probably too much work for something like the Fixtures class. Overkill more than likely.

An exception would be a nice compromise, at least you won't end up with an instance which isn't in an invalid state.

Pascal Voitot Dev

unread,
Sep 20, 2011, 5:49:49 AM9/20/11
to play-fr...@googlegroups.com
On Tue, Sep 20, 2011 at 11:47 AM, James Gregory <jagreg...@gmail.com> wrote:
Yeah, deciding which constructor to use if there isn't a default one is probably a bit of a rabbit hole. I know IoC containers tend to pick the constructor with the most parameters and try to satisfy that... but to be honest, that's probably too much work for something like the Fixtures class. Overkill more than likely.

An exception would be a nice compromise, at least you won't end up with an instance which isn't in an invalid state.

In Siena, I really advise to always create a default constructor...

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To view this discussion on the web visit https://groups.google.com/d/msg/play-framework/-/ON1rloue29QJ.
Reply all
Reply to author
Forward
0 new messages