我有一个重构的Play应用程序。游戏模型已经重构为自己的Maven项目,因此可以与其他项目共享,并且ant-run插件用于增强模型类。
模型可以正常工作,它涉及加载惰性引用(我正在使用公共字段的字段增强)。简单地没有加载引用,并且返回了一个空对象。示例代码是:
@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
当我尝试使用引用的对象时,该对象不为null,但它似乎尚未使用来自数据库的数据进行初始化。
即使B上的id字段也正确填充,但其余字段不是。
Maven似乎正在正确地增强对象(ant-run),因为我可以通过查询来获取对象等。
如果我在Java端指定了.fetch(“b”),则会正确返回该对象,但之前没有必要,有时也无法这样做(在Scala模板中)。
我检查了数据库,相关的对象就在那里。此外,代码在Play项目中工作,但是很多代码(并非所有代码)都停止这样做,因为我将模型移到了Play之外。
application.conf是否有任何特定的配置来指定延迟加载或者我错过了什么?
修改
我已经在Maven项目中添加了一个测试,并使用EBean直接测试了类,而不是使用Play中的Model类,它也不起作用,所以它似乎指向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
}
Play编译器是否做了一些特殊的事情来增强类?我使用ant-run-plugin来增强类,因为我找不到使maven-enhance-plugin工作的方法(它无法找到Play的Model类来检查antrun的增强效果)
编辑2 我已经给#user1664823答案了,因为它有效。但之所以在我的情况下无法工作是因为我提取了游戏中的类以及增强的工作方式。我首先使用直接场进入自己的脚。
Ebean通过修改访问器或修改字段的访问代码来增强类,添加额外的代码来检测访问并执行延迟加载机制(尝试查看增强类的反编译版本)。关于这个问题的一些好评可以在http://www.avaje.org/topic-159.html
看到由于我的课程从主Play项目中脱离到外部Maven项目,并且使用ant完成了增强,因此只增强了Maven项目中的那些类。播放代码无法使用直接字段访问来触发延迟加载机制。
而不是像user1664823那样使用fetch机制(它的工作原理),我已经将代码更改为使用getter和setter,现在延迟加载工作正常。
答案 0 :(得分:0)
从2.0。*升级到2.1。*时遇到了同样的问题。
我发现的唯一解决方案是将fetch(..)
规范添加到我的所有finder调用中。