Scala模板访问Play 2.0中的模型对象属性

时间:2012-03-29 11:36:58

标签: templates playframework playframework-2.0

我有一个关于访问模型对象的成员变量的简单问题。

我有以下模型对象:

@Entity
public class Person extends Model{
    @Id 
    public Long id;
    public String name;
}

@Entity
public class Account extends Model{
    @Id
    public String email;
    public String password;
    @OneToOne
    public Person person;
}

到目前为止一切顺利,任何给定的person都可以有一个account。从zentask示例复制Account对象。身份验证后,我重定向到索引页面,该页面显示Person.name成员变量中所述的用户realname。 Account对象插入到页面中,就像zentasks示例一样:

Account.find.byId(Controller.request().username());

现在模板中发生以下奇怪的事情,我不明白:

@account.person.name

会在调用时在模板中插入Null值:

@account.person.getName()  or   @account.person.getName

按预期结果,从person对象插入正确的名称。

@account.person

显示person对象的.toString(),也正确显示名称。

总结一下:上面的代码出了什么问题?为什么我可以毫无问题地调用account.person值,但是当我调用account.person.name时这不再起作用

提前谢谢!

理查德

3 个答案:

答案 0 :(得分:3)

这是因为JPA使用Aspects来拦截getter使用并从延迟加载的对象中填充缺少的数据。我不知道传统思维是什么,但由于这个原因我不会使用JPA的公共成员,它会一直打破框架。

如果你真的想使用公共成员,你必须将关系标记为渴望获取:

@OneToMany(fetch=FetchType.EAGER)

或显式获取模板中所需的所有对象树(呃)。

在你的情况下,关系,OneToOne是在关系的另一端定义的,如果你在Account端定义它,它应该默认获取eager。我忘记了你是否可以在两个实体上定义OneToOne,我认为你可以,但你可能需要稍微调整一下。

总的来说,不要将公共成员与JPA一起使用,它会破坏。更好的是,抛弃JPA并使用Anorm,它比JPA更成功地映射到问题域。像这样的问题一直导致JPA实现占用的实现时间是任何人似乎能够预测的两倍。

答案 1 :(得分:1)

我偶然发现了Guillaume Bort发布的答案,该答案解释了事情。 在这里阅读:

https://groups.google.com/d/topic/play-framework/CNjH3w_yF6E/discussion

希望这有帮助!

答案 2 :(得分:0)

由于延迟加载,字段中的值只有在从类本身访问时才会被加载。(在正常情况下会使用setter / getter

为了加载你以太必须写入getter和setter的值。 或者您可以创建一个检查每个值的方法。

您可以将以下方法添加到您的帐户实体:

public void checker(){

    if(email==null){}
    if(password==null){}
    if(person==null){}
}

这将加载每个值,但不会降低性能