JDO - 更新一对一子项
我有一个食谱。每个食谱都有一个图像。所以我的实体看起来像
@PersistenceCapable
public class Recipe {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;
@Persistent
private MyImage myImage;
当我第一次创建食谱时,效果很好,图像是 也添加了,我可以查看它。但是当我去更新它时 当
PersistenceManager pm = PMF.get().getPersistenceManager();
Recipe r = pm.getObjectById(Recipe.class, recKey);
try {
r.setImage(newImage);
} finally {
pm.close();
}
新图像添加到数据存储中时,但是当我尝试获取它时 从菜谱中,菜谱仍然指向我的旧图像 数据存储。这是正常的吗?我该如何解决这个问题?
这是我的 jdoconfig.xml 文件的内容
<jdoconfig xmlns="http://java.sun.com/xml/ns/jdo/jdoconfig"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/jdo/jdoconfig">
<persistence-manager-factory name="transactions-optional">
<property name="javax.jdo.PersistenceManagerFactoryClass"
value="org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory"/>
<property name="javax.jdo.option.ConnectionURL" value="appengine"/>
<property name="javax.jdo.option.NontransactionalRead" value="true"/>
<property name="javax.jdo.option.NontransactionalWrite" value="true"/>
<property name="javax.jdo.option.RetainValues" value="true"/>
<property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true"/>
</persistence-manager-factory>
</jdoconfig>
I have a Recipe. Each Recipe has an image. So my entity looks something like
@PersistenceCapable
public class Recipe {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;
@Persistent
private MyImage myImage;
When I create the Recipe the first time, it works great, the image is
added as well and I can view it. However when I go and update it such
as
PersistenceManager pm = PMF.get().getPersistenceManager();
Recipe r = pm.getObjectById(Recipe.class, recKey);
try {
r.setImage(newImage);
} finally {
pm.close();
}
the new image is added to the data-store, but when I try and fetch it
from within the recipe, the recipe still points to the old image in my
data-store. Is this normal? How can I fix this?
Here is the content of my jdoconfig.xml file
<jdoconfig xmlns="http://java.sun.com/xml/ns/jdo/jdoconfig"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/jdo/jdoconfig">
<persistence-manager-factory name="transactions-optional">
<property name="javax.jdo.PersistenceManagerFactoryClass"
value="org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory"/>
<property name="javax.jdo.option.ConnectionURL" value="appengine"/>
<property name="javax.jdo.option.NontransactionalRead" value="true"/>
<property name="javax.jdo.option.NontransactionalWrite" value="true"/>
<property name="javax.jdo.option.RetainValues" value="true"/>
<property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true"/>
</persistence-manager-factory>
</jdoconfig>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我认为 JDO 的 AppEngine 实现以父键的形式存储拥有的关系。当您将 myImageA 设置为recipe1 的子级时,appengine 将 MyImage 实体的父级设置为recipe1。
我不是这方面的专家,但我猜测当您将 myImageB 作为recipe1 的子级时,appengine 只是将另一个 MyImage 实体的父级设置为recipe1。当它去检索
myImage
时,它会查找父级为recipe1
的图像,并且仍然找到myImageA
,即使myImageB
仍然坐在那里。我再次猜测。我希望有一个“提交猜测”选项。
TL;DR:我会在设置
myImageB
之前尝试显式删除myImageA
。这会破坏对myImageA
的所有其他引用,但如果您希望从其他上下文中使用它,那么拥有的关系无论如何都是不合适的。这种令人困惑的混淆就是我放弃 JDO 和 JDO 的原因。完全拥有关系并学会了热爱 Objectify。它们还限制了您对实体组的选择,这增加了雾的另一个维度。
I think the AppEngine implementation of JDO stores owned relationships in the form of parent keys. When you make myImageA a child of recipe1, appengine sets the parent of a MyImage entity to recipe1.
I'm not an expert on this, but I'm guessing that when you make myImageB a child of recipe1, appengine just sets the parent of another MyImage entity to recipe1. When it goes to retrieve
myImage
, it looks for an image with a parent ofrecipe1
, and still findsmyImageA
, even thoughmyImageB
is still sitting there.Again, I'm guessing. I wish there was a "Submit Guess" option.
TL;DR: I'd try deleting
myImageA
explicitly before settingmyImageB
. That would break every other reference tomyImageA
, but if you're hoping to use it from other contexts an owned relationship is inappropriate anyway.This kind of confusing mixup is why I dropped JDO & owned relationships altogether and learned to love Objectify. They also constrain your options for entity groups, which adds another dimension of fog.
我认为您必须在设置新图像对象后调用
pm.makePercient(r);
才能实际保留您的更改。I think you got to call
pm.makePersistent(r);
after setting the new image object to actually persist your change.不需要执行
pm.makePercient(r);
因为 Recipe 已经是持久的。但在您的代码示例中,您使用非事务性读取,这意味着您可以在没有事务的情况下从数据存储区读取实例。
但如果你想进行持久修改,你需要使用事务。
It is not required to do
pm.makePersistent(r);
because the Recipe is already persistent.But in your code example you use non transactional read which means you can read instances from the datastore without a Transaction.
But if you want to do persistent modifications you need to use a Transaction.
对我有用的是获取需要更新的旧对象,然后更改该对象,然后存储它。调整你的代码给了我们:
这基本上就是我所做的,而且似乎有效。
What worked for me was getting the old object that needed to be updated then changing the object then storing it. Adjusting your code gives us:
This is basically what I did and it seems to work.