【问题标题】:JDO persists all fields as nullJDO 将所有字段保持为空
【发布时间】:2014-01-23 02:30:25
【问题描述】:

我有以下情况:

一个“Account”类,它应该包含一个“Money”对象的集合。

@PersistenceCapable
public class Account extends Entity {
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    @Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
    private String id;

    @Expose
    @Persistent
    private String name;

    /**
     * The initial balance should be a portfolio, e.g. 300 BGN, 230 EUR etc.
     */
    @Expose
    @Persistent
    private List<Money> initialBalancePortfolio;

“Money”类看起来是这样的:

public class Money {
    @Persistent
    @Extension(vendorName = "datanucleus", key = "gae.unindexed", value = "true")
    private BigDecimal ammount;

    @Persistent
    private String currency;

问题来了:

  1. 我不希望所有货币实例都使用单独的表。我尝试在使用 @Embedded 注释时实现它,但这是不可能的,因为 initialBalancePortfolio 本身无法嵌入(集合)。
  2. 我放弃并尝试存储帐户对象 (pm.makePersistent(...))。我希望这种方式也可以存储货币对象。这实际上是正确的,但所有对象字段都是空的。

这个测试用例说明了问题:

    @Test
    public void initialBalancePortfolioShouldBePersisted() throws Exception {
        //create
        Account account = createAccount();
        AccountDao accountDao = new AccountDao();
        accountDao.create(account);
        //get it with new dao
        AccountDao newAccountDao = new AccountDao();
        Account newAccount = newAccountDao.readAll().get(0);
        assertEquals(account.getInitialBalancePortfolio(), newAccount.getInitialBalancePortfolio());
    }

    private Account createAccount() {
        //create list with money
        List<Money> money = new ArrayList<Money>();
        Money m1 = new Money(23, "BGN");
        Money m2 = new Money(21, "EUR");
        money.add(m1);
        money.add(m2);
        //create account 
        Account account = new Account(accEntity, money, "xxx");
        return account;
    }

JUnit 异常:

java.lang.AssertionError: expected:<[Money [ammount=23, currency=BGN], Money [ammount=21, currency=EUR]]> but was:<[Money [ammount=null, currency=null], Money [ammount=null, currency=null]]>

编辑:

对象创建的持久化代码:

/**
 * Create entity. entityDao.create(entity);
 * 
 * @param t
 *            Entity
 * @return operations success
 */
public boolean create(T t) {
    if (t.getId() == null) {
        PersistenceManager pm = PMF.getInstance().getPersistenceManager();
        try {
            pm.makePersistent(t);
            LOGGER.info(getEntityClass() + " created!");
            return true;
        } finally {
            pm.close();
        }
    } else {
        LOGGER.info(getEntityClass() + " already exist! Update only!");
        update(t);
        return false;
    }
}

对于对象检索:

/**
 * Get all existing objects.
 * 
 * @return
 */
public List<T> readAll() {
    PersistenceManager pm = PMF.getInstance().getPersistenceManager();
    try {
        pm.getFetchPlan().setGroup(FetchGroup.ALL);
        Query q = pm.newQuery(getEntityClass());
        @SuppressWarnings("unchecked")
        List<T> allEntities = (List<T>) q.execute();
        return allEntities;
    } finally {
        pm.close();
    }
}

【问题讨论】:

  • 没有发布持久性代码,所以让人们猜测 DAO 中的内容是什么?貌似也没有看日志。当您查看对象时,没有查看对象处于什么“状态”(同样,您没有说明持久性代码中的位置,所以只能猜测)
  • 感谢您的评论。我添加了我的持久性代码。我希望它能给你一些额外的信息。
  • 那么对象处于什么状态?你没有说你在哪里检查字段值。您很可能没有将它们分离,因此它们是 HOLLOW ,因此显然这些字段为空(除非您根据所有 JDO 文档设置 javax.jdo.option.RetainValues )。这就是日志给你的。不知道为什么要在持久化时设置 FetchPlan,它是用于 FETCHing
  • 我(JUnit 正在)检查 assertEquals 语句中的字段值。查看 JUnit 异常。你能告诉我如何分离它们(以及在哪里)吗?谢谢!
  • 忽略日志意味着不了解问题。当生命周期操作发生时,将事物放入 txn 可能会发生变化,但这一切都取决于持久性属性,我们看不到设置了哪些。如果你得到你想要的答案,任何解决方案都没有“错误”

标签: java google-app-engine persistence jdo datanucleus


【解决方案1】:

我已经找到了解决问题的方法。

关于 JDO 如何管理对象生命周期的一些背景信息: http://db.apache.org/jdo/state_transition.html

以及解决方案本身:

PersistenceManager pm = PMF.getInstance().getPersistenceManager();
Transaction tx = pm.currentTransaction();
try {
    tx.begin();
    pm.makePersistent(t);
    tx.commit();
} catch (Exception e) {
    LOGGER.severe("Exception by creating a new entity "
            + e.getMessage());
    tx.rollback();
} finally {
    pm.close();
}

如您所见,我正在使用事务来确保对象处于有效状态。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-04
    • 2011-11-30
    • 2013-02-11
    • 1970-01-01
    • 2018-03-29
    • 1970-01-01
    • 2011-06-05
    • 2014-10-21
    相关资源
    最近更新 更多