【发布时间】: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;
问题来了:
- 我不希望所有货币实例都使用单独的表。我尝试在使用 @Embedded 注释时实现它,但这是不可能的,因为 initialBalancePortfolio 本身无法嵌入(集合)。
- 我放弃并尝试存储帐户对象 (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