使用不加载惰性对象的 Maven 增强模型播放 2.1.3 应用程序

Posted

技术标签:

【中文标题】使用不加载惰性对象的 Maven 增强模型播放 2.1.3 应用程序【英文标题】:Play 2.1.3 application with Maven enhanced models not loading lazy objects 【发布时间】:2013-09-11 11:39:19 【问题描述】:

我有一个经过重构的 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 

当我尝试使用引用的对象时,该对象不为空,但似乎尚未使用数据库中的数据对其进行初始化。

即使 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看到一些关于该主题的优秀cmets@

由于我的类从 Play 主项目转移到外部 Maven 项目中,并且使用 ant 完成了增强,因此仅增强了 Maven 项目中的那些类。播放代码无法使用直接字段访问触发延迟加载机制。

我没有像 user1664823 所说的那样使用 fetch 机制(它是这样工作的),而是将代码更改为使用 getter 和 setter,现在延迟加载可以正常工作了。

【问题讨论】:

【参考方案1】:

我从 2.0.* 升级到 2.1.* 时遇到了同样的问题。 我找到的唯一解决方案是将fetch(..) 规范添加到我所有的查找器调用中。

【讨论】:

感谢您的回复,但奇怪的是它之前工作过。由于会话的安全问题,它已从 Play 2.1.0 升级到 2.1.3,但到目前为止它运行良好。当它停止工作时,它是在将代码重构到自己的项目中之后 是的,它在我重构 Play 2.1.0 和 2.1.3 之前就可以工作。该项目从 2.1.0 开始,发现通过延迟加载等直接访问字段非常简洁。但是当我将它移到 Play 项目源代码之外时,它就停止了工作。我找到了为什么我的代码不起作用并在第二次编辑中给出了解释

以上是关于使用不加载惰性对象的 Maven 增强模型播放 2.1.3 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

如何从对象检测数据加载器中的马赛克增强中获取类标签?

从外部 API 播放模型对象

如何使用 SQLAlchemy 找出是不是还没有加载惰性关系?

每周分享第 1 期(2019.4.6)

ActiveRecord 惰性加载,和使用gem faker

局域网内搭建私人影院 手机端也能播放 增强版