1

我在 Play 1.2.x 应用程序中发现了奇怪的行为

例如我们有以下代码:

应用程序/模型/Account.java:

package models;

import javax.persistence.Entity;

import play.db.jpa.Model;

@Entity
public class Account extends Model {

    public String username;
}

应用程序/coutrollers/Application.java:

package controllers;

import play.mvc.Controller;

import java.util.List;

import models.Account;

public class Application extends Controller {

    public static void index() {
        Account account = Account.find("username LIKE ?", "username1").first();
        account.username = "username3";
        List<Account> accounts = Account.all().fetch();
        render(account, accounts);
    }
}

应用程序/视图/应用程序/index.html:

#{extends 'main.html' /}
#{set title:'Home' /}

<h2>Working!</h2>

${account.username}

<ul>
  #{list items:accounts, as:'acc'}
    <li>${acc.username}</li>
  #{/list}
</ul>

在数据库中有以下帐户:

  • 用户名1
  • 用户名2

输出将如下:

在职的!

用户名3

  • 用户名3
  • 用户名2

但必须为:

在职的!

用户名3

  • 用户名1
  • 用户名2

这是什么???

  • 玩虫子?
  • Java 静态上下文特性?
  • JPA 功能?
  • ...?

解决

感谢@millimoose。所有需要的是detach()

package controllers;

import play.mvc.Controller;

import java.util.List;

import models.Account;

import play.db.jpa.JPA;

public class Application extends Controller {

    public static void index() {
        Account account = Account.find("username LIKE ?", "username1").first();
        account.username = "username3";
        JPA.em().detach(account);
        List<Account> accounts = Account.all().fetch();
        render(account, accounts);
    }
}
4

1 回答 1

2

JPA 的工作方式与地球上的所有其他 ORM 一样,当您查找相同的数据库记录两次时,您将获得相同的对象。该.first()查询在Account内部缓存(以跟踪在一个工作单元内对其所做的更改),并且该.all().fetch()调用只是再次为您提供该缓存的对象。

我对游戏不熟悉!ORM 的东西,但“原始”JPA 必须EntityManager.detach()让它停止跟踪给定的实体实例。(因此,每当再次检索到相应的数据库记录时,都会为您提供一个新副本。)

于 2013-03-19T11:50:46.867 回答