渴望获取似乎没有加入 [英] Eager fetch does not seem to join

查看:74
本文介绍了渴望获取似乎没有加入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Java中使用play 2.0.4.我试图从播放提供的内存数据库中保存和检索一个值(Ebean是底层JPA实现). 这是一些示例代码:

I'm using play 2.0.4 with Java. I'm trying to save and retrieve a value from the in-memory db that play provides (Ebean is the underlying JPA implementation). Here's some sample code:

@NoobDisclaimer ("I'm fairly new to Play and JPA")
@Entity
public class User extends Model {

@Id
public Long id;

public String name;

// Does not fetch eagerly.
@ManyToOne(fetch=FetchType.EAGER)
private Role role; // Role extends Model { has id and name}

public static Finder<Long, User> find = new Finder<Long, User>(Long.class, User.class);

public static List<User> all() {
    List<User> allUsers = find.all();
    for (User u : allUsers) {
        System.out.println("User:" + u.id + "|" + u.name); // SOP1
        // System.out.println("Assoc Role:" + u.role.name); //SOP2
    }
    return allUsers;
}

public static void create(User user) {
    user.save();
}

}

在index.scala.html中, @(用户:列表[用户],用户窗体:表单[用户])

In index.scala.html, @(users: List[User], userForm: Form[User])

<h2>@users.size() user(s) found!</h2>
        <ul>
            @for(usr <- users) {
                <li>Name: @usr.name</li> <!-- Displayed -->
                <li>Role: @usr.role.name</li> <!-- Displays blank value -->
            }
        </ul>

问题是当我在控制器中执行User.all()并将其发送到视图时,未加载user.role,即@ usr.role.name为空白.也不例外.我已经设置了SQL调试功能,并且已经验证了角色"表的外键已保存在用户"表中.当我在User.all()方法中打印角色名称时(请参见SOP2),将触发查询并打印角色名称.它还显示在视图上.

The problem is that when I do a User.all() in the controller and send it to the view, user.role is not loaded, i.e., @usr.role.name is blank. There is no exception. I have set SQL debugging on and I have verified that a foreign key to the Role table is saved in the User table. When I print the role name in the User.all() method (see SOP2), a query is fired and the role name is printed. It also shows up on the view.

我知道,默认情况下,该角色将被延迟加载,并且PersistenceContext在模板中将不可用以加载与用户相关联的角色.但是,渴望不能使我为一个物体找到所有联想到的实体吗?我是新来的 Play和JPA,我无法弄清楚如何在加载某些东西时不经过每个相关实体的情况下使它工作.有什么我想念的吗?

I understand that, by default, the role would be lazily loaded and that the PersistenceContext would not be available in the template to load the role associated with the user. However, shouldn't an eager fetch get me all assocaited entites for an object? I'm fairly new to Play and JPA and I can't figure out how to get this to work without going through each associated entity when I load something. Is there something I'm missing?

在相关说明中,如果必须使用懒惰提取,如何确保在提取用户时视图中可以使用user.role?

On a related note, if I had to use lazy fetch, how do I ensure that the user.role is available to the view when I fetch a user?

推荐答案

Ebean是基础的JPA实现

Ebean不是JPA实现. Ebean与JPA标准有一些共同点.它看起来有点相似,因为它的注释看起来与JPA相似.

Ebean is not a JPA Implementation. Ebean has a little in common with the JPA standard. It looks a little similar, because it's annotations look similar to JPA's.

问题的原因:Ebean不支持@ManyToMany批注上的fetch = ...属性.

2个解决方案:

  1. 从批注中删除fetch = ...,而对play.db.ebean.Model.Finder<I,T>对象(实现com.avaje.ebean.Query<T>)或com.avaje.ebean.Ebean对象使用fetch()方法.

  1. Remove fetch=... from annotation and instead use fetch() method on either the play.db.ebean.Model.Finder<I,T> object (which implements com.avaje.ebean.Query<T>) or the com.avaje.ebean.Ebean object.

问题是这里有两个单独的持久库(play.db.ebean和com.avaje.ebean),它们之间的集成是一个挑战和问题.
例如. play.db.ebean.Model.Finder.fetch()方法返回com.avaje.ebean.Query<T>而不是play.db.ebean.Model.Finder-我发现这没有帮助,因为它使您脱离了Play API模型帮助器.显然,在调用fetch()之后,您将无法再使用Model.Finder方法-那时,帮助器"类不多.
老实说,我认为获取功能不是Play API的一流功能-最好遵照Avaje API.

Problem is there are two separate persistent libraries here (play.db.ebean and com.avaje.ebean) and integration between them is a challenge and issue.
E.g. play.db.ebean.Model.Finder.fetch() method returns com.avaje.ebean.Query<T> rather than play.db.ebean.Model.Finder - which I find unhelpful as it takes you away from the play API Model helper. After calling fetch() apparently you can no longer use the Model.Finder methods - not much of a "helper" class at that point.
To be honest, I don't think the fetch functionality is a first class feature within Play API yet - best to defer to the Avaje API.

在Avaje API中使用fetch()的两个示例:

Two examples of using fetch() from within the Avaje API:

// single SQL query with a fetch join
List<Order> l0 = Ebean.find(Order.class)
.fetch("customer")
.findList();

// two separate SQL queries
List<Order> l0 = Ebean.find(Order.class)
.fetch("customer", new FetchConfig().query())
.findList();

注意:对Ebean的最新发行版/更新(不包括错误修复)是2010年11月6日-整整2年前. Ebean的吸收率非常低.

切换到在Play中使用JPA 2.0实现. JPA 2.0版本确实非常强大,易于使用并且得到了广泛的支持.这可能意味着Ebean的死亡.请注意,Play已在2.0中添加了以下配置功能(在1.1中未提供)-表明Play正朝着从任何提供商全面支持JPA的方向发展. http://www.playframework.org/documentation/2.0/JavaJPA

Switch to using a JPA 2.0 implementation within Play. The 2.0 release of JPA is very powerful indeed, is easy to use, and is very widely supported. It will probably mean the death of Ebean. Note that Play has added the following configuration feature into 2.0 (wasn't present in 1.1) - suggesting Play is moving towards fuller support for JPA from any provider. http://www.playframework.org/documentation/2.0/JavaJPA

完成此操作后,请停止使用play.db类和com.avaje类-我建议您使用100%javax.persistence类.

Once you do this, stop using play.db classes and com.avaje classes - I suggest you use 100% javax.persistence classes.

这篇关于渴望获取似乎没有加入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆