在 Google Appengine 上使用 JDO 交换列表中的两个元素
我有一个 TestEntity,它有一个 ChildEntities 的 ArrayList。他们建立了一种拥有关系。我想要 从数据存储中获取实体,更新子实体中的 int 字段 实体,然后交换两个子实体的位置。 然而,一旦我交换实体,看起来好像 对 int 字段的更新被删除。我是否不允许存储 JDO 将对象保留在临时变量中以进行交换?这是我的测试 代码,后面是实体本身的定义。当我 单步执行调试器中的代码,我的 ChildEntity 被覆盖 或者当我将第二个值复制到列表中的位置 0 时立即重置或执行其他操作。恐怕我缺少一些有关 JDO 工作原理的信息。
@Test
public void testSwap() {
PersistenceManager pm = PMF.get().getPersistenceManager();
TestEntity te = new TestEntity();
pm.makePersistent(te);
te.getChildEntities().add(new TestChildEntity("a"));
te.getChildEntities().add(new TestChildEntity("b"));
long id = te.getId();
pm.close();
pm = PMF.get().getPersistenceManager();
te = pm.getObjectById(TestEntity.class, id);
List<TestChildEntity> children = te.getChildEntities();
for (TestChildEntity tce : children) {
tce.setFoo(3);
}
TestChildEntity temp = children.get(0);
children.set(0, children.get(1));
// after the above line executes, the object referred to by temp is overwritten/reset when i watch in debugger.
children.set(1, temp);
assertEquals(3, children.get(0).getFoo()); // these asserts will both fail.
assertEquals(3, children.get(1).getFoo());
}
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class TestEntity {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;
@Persistent(mappedBy = "parent")
private List<TestChildEntity> childEntities;
public List<TestChildEntity> getChildEntities() {
return childEntities;
}
public Long getId() {
return id;
}
public static void demonstrateProblemWithRemove() {
PersistenceManager pm = PMF.get().getPersistenceManager();
TestEntity te = new TestEntity();
pm.makePersistent(te);
te.getChildEntities().add(new TestChildEntity("a"));
te.getChildEntities().remove(0);
pm.close();
}
}
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class TestChildEntity {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
@Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value
= "true")
private String encodedKey;
@Persistent
@Extension(vendorName = "datanucleus", key = "gae.pk-name", value =
"true")
private String keyName;
@Persistent
private int foo;
@Persistent
private TestEntity parent;
public TestChildEntity(String k) {
this.keyName = k;
this.foo = 1;
}
public int getFoo() {
return foo;
}
public void setFoo(int foo) {
this.foo = foo;
}
I have a TestEntity that has an ArrayList of ChildEntities. They are joined in a owned relationship. I want to
get the Entity from the datastore, update an int field in the child
entity, and then swap the position of the two child entities.
However, as soon as I swap the entities, it appears as though the
updates to the int field are erased. Am I not allowed to store a JDO
persisted object in a temp variable to do the swap? Here is my test
code, followed by the definitions of the Entities themselves. When I
step through the code in the debugger, my ChildEntity gets overwritten
or reset or whatever as soon as I copy the 2nd value into position 0 in the list. I'm afraid there's something about how JDO works that I am missing.
@Test
public void testSwap() {
PersistenceManager pm = PMF.get().getPersistenceManager();
TestEntity te = new TestEntity();
pm.makePersistent(te);
te.getChildEntities().add(new TestChildEntity("a"));
te.getChildEntities().add(new TestChildEntity("b"));
long id = te.getId();
pm.close();
pm = PMF.get().getPersistenceManager();
te = pm.getObjectById(TestEntity.class, id);
List<TestChildEntity> children = te.getChildEntities();
for (TestChildEntity tce : children) {
tce.setFoo(3);
}
TestChildEntity temp = children.get(0);
children.set(0, children.get(1));
// after the above line executes, the object referred to by temp is overwritten/reset when i watch in debugger.
children.set(1, temp);
assertEquals(3, children.get(0).getFoo()); // these asserts will both fail.
assertEquals(3, children.get(1).getFoo());
}
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class TestEntity {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;
@Persistent(mappedBy = "parent")
private List<TestChildEntity> childEntities;
public List<TestChildEntity> getChildEntities() {
return childEntities;
}
public Long getId() {
return id;
}
public static void demonstrateProblemWithRemove() {
PersistenceManager pm = PMF.get().getPersistenceManager();
TestEntity te = new TestEntity();
pm.makePersistent(te);
te.getChildEntities().add(new TestChildEntity("a"));
te.getChildEntities().remove(0);
pm.close();
}
}
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class TestChildEntity {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
@Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value
= "true")
private String encodedKey;
@Persistent
@Extension(vendorName = "datanucleus", key = "gae.pk-name", value =
"true")
private String keyName;
@Persistent
private int foo;
@Persistent
private TestEntity parent;
public TestChildEntity(String k) {
this.keyName = k;
this.foo = 1;
}
public int getFoo() {
return foo;
}
public void setFoo(int foo) {
this.foo = foo;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尝试将 defaultFetchGroup = "true" 添加到 TestEntity.childEntities 上方的 @Persistent 注释中。
默认情况下,不会从数据存储区获取 childEntities(这是 JDO 行为,据我所知,与 AppEngine 无关)。我想,就你的情况而言,它们甚至没有被写入,因为你在添加子项之前调用了 makePersistent 。
Try adding defaultFetchGroup = "true" to @Persistent annotation above TestEntity.childEntities
By default, childEntities aren't fetched from datastore (it is JDO behavior, as far as I know, nothing specific to AppEngine). In your case, I suppose, they are even not written because you call makePersistent before you add children.