JDO将所有字段保持为null

时间:2014-01-05 18:10:28

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

我有以下情况:

“帐户”类,应包含“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本身无法嵌入(Collection),因此无法实现。
  2. 我放弃并试图存储帐户对象(pm.makePersistent(...))。我希望通过这种方式存储货币对象。这实际上是正确的,但所有对象字段都是null。
  3. 此测试用例显示了问题:

        @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();
        }
    }
    

1 个答案:

答案 0 :(得分:0)

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

有关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();
}

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