Play 2.1.3 application with Maven enhanced models not loading lazy objects

懵懂的女人 提交于 2019-12-13 05:16:50

问题


I have a Play application that is been refactored. The play models have been refactored out to its own Maven project so they can be shared with other projects, and the ant-run plugin is being used to enhance the model classes.

The models work ok up to the point that it involves loading the lazy references (I'm using field enhancement with public fields). The references are simply not loaded and an empty object is beeing returned. The example code is:

@Entity
class A extends Model {

   @Id
   @GeneratedValue(strategy=GenerationType.IDENTITY)
   public int id;

   @ManyToOne
   public B b;

   public static Finder<Integer,A> finder = new Finder<Integer,A>(Integer.class, A.class);
}

@Entity
class B extends Model {

   @Id
   @GeneratedValue(strategy=GenerationType.IDENTITY)
   public int id;

   public String someField;  
}
....
....
A a = A.finder.by(someId); // returns the correct object
B b = a.b; // Returns a not null but empty object
System.out.println(b.someField); // someField is always null 

When I try to use the referenced object the object is not null, but it seems it hasn't been initialized with data from the DB.

Even the id field on the B is populated correctly, but the rest of the fields are not.

Maven seems to be enhancing the objects correctly (ant-run) since I can get the objects with queries, etc.

If I specify .fetch("b") on the Java side the object is returned correctly, but it wasn't necessary before, and sometimes is not possible to do so (in the Scala templates).

I've checked the DB and the related objects are there. Also the code was working while it was inside the Play project, but a lot of code (not all) has stopped doing so since I moved the models outside Play.

Are there any specific configs for application.conf to specify lazy loading or am I missing something?

Edit:

I have added a tests to the Maven project and tested directly the classes with EBean instead of using the Model class from Play and it doesn't work either, so it seems to point Avaje Enorm:

List<A> aS = server.find(A.class).findList();
for (A a : aS) {
   B b = a.b;
   System.out.println("Prop: " + a.b.someProperty); // prints Prop: null
   b.refresh();
   System.out.println("Prop: " + a.b.someProperty); // prints correctly the value
}

Does the Play compiler do something special to enhance the classes? I use the ant-run-plugin to enhance the classes because I can't find a way to make the maven-enhance-plugin work (it can't find Play's Model class to check for enhancement while the antrun does)

Edit 2 I've given #user1664823 answer as right, because it works. But the reason why it is not working in my case is because I extracted the classes out of play and the way the enhancement works. I shot myself on the foot by using direct field access in the first place.

Ebean enhances the classes by modifying the accessors or modifying the access code to the fields, adding extra code to detect the access and execute the lazy loading mechanism (try to see the decompiled version of your enhanced class). Some good comments on the subject can be seen at http://www.avaje.org/topic-159.html

Since my classes got out of the main Play project into an external Maven project, and the enhancement was done with ant, only those classes in the Maven project were enhanced. Play code was not able to trigger the lazy loading mechanism using direct field access.

Instead of using the fetch mechanism as user1664823 said (it works that way), I have changed the code to use getters and setters and now the lazy loading works ok.


回答1:


I had the same problem while upgrading from 2.0.* to 2.1.*. The only solution I found was adding the fetch(..) spec to all of my finder calls.



来源:https://stackoverflow.com/questions/18740141/play-2-1-3-application-with-maven-enhanced-models-not-loading-lazy-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!