本文介绍了Gae Jdo坚持一对多拥有双向导航的关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我手动将添加到到 User
class,我期望最后 Contact
将会有对父节点 User
对象的引用。
- 如果我在坚持父对象之前手动配置它,我会得到一个
异常: org。 datanucleus.store.appengine.DatastoreRelationFieldManager.checkForParentSwitch(DatastoreRelationFieldManager.java:204)
- 在
User
对象持久性父引用不是
更新。
- 使用密钥从
数据存储中检索 Contact
对象后,父引用不会更新。 >
我不明白我的错误所在。
包测试;
import java.util.ArrayList;
import java.util.List;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import com.google.appengine.api.datastore.Key;
public class DatastoreJdoTest extends LocalServiceTestCase {
@Autowired
@Qualifier(persistenceManagerFactory)
PersistenceManagerFactory pmf;
@Test
public void testBatchInsert(){
Key keyKey;
PersistenceManager pm = pmf.getPersistenceManager();
try {
pm.currentTransaction()。begin();
User user = new User();
联系人联系人=新联系人(contact1);
user.contacts.add(contact);
$ b $ * *
*由此抛出异常
*
*检测到建立User(1)/ Contact(2)作为$ b的父项的尝试$ b *用户(1),但由用户(1)标识的实体已经被
*持久化,没有父母。一旦对象被保存,父代不能建立或者
*改变。
* org.datanucleus.store.appengine.FatalNucleusUserException:
*检测到建立User(1)/ Contact(2)作为
* User(1)的父项的尝试,但确定的实体由用户(1)已经被
*坚持没有父母。一旦对象被保存,父代不能建立或者
*改变。 at
* org.datanucleus.store
* .appengine.DatastoreRelationFieldManager.checkForParentSwitch
*(DatastoreRelationFieldManager.java:204)
* /
//contact.user =用户;
Assert.assertNull(contact.key);
pm.makePersistent(user);
Assert.assertNotNull(contact.key);
pm.currentTransaction()。commit();
contactKey = contact.key;
//这个断言被破坏了。为什么?
//Assert.assertNotNull (contact.user);
} finally {
if(pm.currentTransaction()。isActive()){
pm.currentTransaction()。rollback();
}
}
联系contact2 = pm.getObjectById(Contact.class,contactKey);
Assert.assertNotNull(contact2);
//这个断言被破坏了。为什么联系人不存储父母用户?
Assert.assertNotNull(contact2.user);
@PersistenceCapable(identityType = IdentityType.APPLICATION,detachable =true)
class User {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
公钥键;
@Persistent
公共字符串名称;
@Persistent
public List< Contact> contacts = new ArrayList< Contact>();
@PersistenceCapable(identityType = IdentityType.APPLICATION,detachable =true)
class Contact {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
Key key;
@Persistent
public String contact;
@Persistent(mappedBy =contacts,dependent =true)
public用户用户;
public Contact(String contact){
this.contact = contact;
$ div $解析方案
要,您应指定mappedBy您的关系的所有者。
您可能还想阅读或查看从子对象(消息)访问父(讨论)它是从查询中获取的
I'm trying to persist a one-to-many owned relationship with bidirectional navigation in GAE using JDO.
I manually add the Contact
to User
class, and I would expect that in the end the Contact
will have a reference to the parent User
object.
- If I configure this manually before I persist the parent, I get an
exception:
org.datanucleus.store.appengine.DatastoreRelationFieldManager.checkForParentSwitch(DatastoreRelationFieldManager.java:204)
- After the
User
object persistence the parent reference is not
updated.
- After the
Contact
object is retrieved from the
datastore using the key the parent reference is not updated.
I don't understand where my mistake is.
package test;
import java.util.ArrayList;
import java.util.List;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import com.google.appengine.api.datastore.Key;
public class DatastoreJdoTest extends LocalServiceTestCase {
@Autowired
@Qualifier("persistenceManagerFactory")
PersistenceManagerFactory pmf;
@Test
public void testBatchInsert() {
Key contactKey;
PersistenceManager pm = pmf.getPersistenceManager();
try {
pm.currentTransaction().begin();
User user = new User();
Contact contact = new Contact("contact1");
user.contacts.add(contact);
/*
* With this an exception is thrown
*
* Detected attempt to establish User(1)/Contact(2) as the parent of
* User(1) but the entity identified by User(1) has already been
* persisted without a parent. A parent cannot be established or
* changed once an object has been persisted.
* org.datanucleus.store.appengine.FatalNucleusUserException:
* Detected attempt to establish User(1)/Contact(2) as the parent of
* User(1) but the entity identified by User(1) has already been
* persisted without a parent. A parent cannot be established or
* changed once an object has been persisted. at
* org.datanucleus.store
* .appengine.DatastoreRelationFieldManager.checkForParentSwitch
* (DatastoreRelationFieldManager.java:204)
*/
//contact.user = user;
Assert.assertNull(contact.key);
pm.makePersistent(user);
Assert.assertNotNull(contact.key);
pm.currentTransaction().commit();
contactKey = contact.key;
//this assertion is broken. why ?
//Assert.assertNotNull(contact.user);
} finally {
if (pm.currentTransaction().isActive()) {
pm.currentTransaction().rollback();
}
}
Contact contact2 = pm.getObjectById(Contact.class, contactKey);
Assert.assertNotNull(contact2);
//this assertion is broken. why the contact don't store the parent user ?
Assert.assertNotNull(contact2.user);
}
}
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
class User {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
public Key key;
@Persistent
public String name;
@Persistent
public List<Contact> contacts = new ArrayList<Contact>();
}
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
class Contact {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
Key key;
@Persistent
public String contact;
@Persistent(mappedBy = "contacts", dependent = "true")
public User user;
public Contact(String contact) {
this.contact = contact;
}
}
解决方案
According to App Engine docs, you should specify "mappedBy" in the owner of your relationship.
You may also want to read Max Ross's article or to have a look at my code which accesses parent (Discussion) from a child object (Message) which is fetched from a query
这篇关于Gae Jdo坚持一对多拥有双向导航的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!