在JDO中使用一对多拥有的关系 - AppEngine

时间:2013-03-09 14:49:49

标签: java google-app-engine entity-relationship one-to-many jdo

我是JDO及其概念的新手。之前我和ORMLite一起工作非常简单,我无法弄清楚如何在JDO中做我在ORMLite中所做的事情。 我有2个实体,BroadcastMovie。每个Broadcast都有一个MovieMovie可以有多个Broadcasts个。 不生成广播的ID,在保持广播之前配置它。 所以这就是我所做的:

@PersistenceCapable
public class Broadcast {

    @PrimaryKey
    private String id;

    @Persistent
    private Movie movie;

    //More fields....
}

现在这是Movie类(再次生成id,在保存对象之前配置它):

@PersistenceCapable
public class Movie {

    @PrimaryKey
    private String id;

    @Persistent(mappedBy = "movie")
    private List<Broadcast> broadcasts;

    //More fields....
}

现在,我有一个servlet,它正在获取并保存数据库中的所有数据。 首先,我获取所有Broadcasts,对于每个Broadcast的电影我知道的是标题及其ID,因此我将Broadcast保存为Movie个对象在它中有一个事务(因为有两个被保存的对象,所以这必须是原子操作):

// Check if this broadcast already exist.
try {
     mgr.getObjectById(Broadcast.class, brdcst.getId());
} catch (Exception e) {
     if(e instanceof JDOObjectNotFoundException){
    Transaction tx = null;
    try{
        tx = mgr.currentTransaction();
        tx.begin();
        mgr.makePersistent(brdcst);
        tx.commit();
    }
    catch(Exception e1){
        sLogger.log(Level.WARNING, e.getMessage());
    }
    finally{
        if (tx.isActive()) {
            tx.rollback();
        }
        mgr.flush();
    }

     }
     else sLogger.log(Level.WARNING, e.getMessage());
}

然后,我正在获取电影的数据并保存它,使用相同的ID,覆盖前一个对象(在没有引用Broadcast对象的其他线程中)。

try {
    sLogger.log(Level.INFO, "Added the movie: " + movie);
    mgr.makePersistent(movie);
} catch (Exception e) {
    e.printStackTrace();
}
finally{
    mgr.flush();
}

所以,要明确一点,这就是ORMLite中发生的事情以及我想在这里发生的事情。 当我保存Broadcast对象时,我正在添加带有ID的影片,因此将来这个ID将帮助他在数据库中引用它的Movie

但是每当我向数据库查询广播并希望在其中找到对电影的引用时,我得到的都是null或者这个例外:

Field Broadcast.movie should be able to provide a reference to its parent but the entity does not have a parent.  Did you perhaps try to establish an instance of Broadcast as the child of an instance of Movie after the child had already been persisted?

那么,我在这里做错了什么?

3 个答案:

答案 0 :(得分:1)

要在GAE中使用关系,您必须使用com.google.appengine.api.datastore.Key而不是long或String键。 Example

答案 1 :(得分:1)

对这里发生了什么有点解释: 我从网上获取了List个广播。列表中的每个广播都有一个Movie对象(Broadcast.setMovie),它只有一个标题。 我的目的是迭代这个广播列表并获取每个Broadcast电影所需的信息(这就是我在每个操作结束时使用mgr.flush()的原因)。 因此,首先我将广播添加到数据存储区(如果它不存在),然后获取电影的数据并将其保留。 我有一个问题,在ORMLite中,当你有一个外来的字段,并且你存储了这个对象时,框架就是保存这个对象和外部字段对象的id。 所以,假设我有一个id = 10的广播和一个id为2的电影,框架会将广播保存到数据库中,电影字段为2。 所以这就是我想在这里做的事情,但在JDO中它不是这样的。 按照@Noofiz在他的回答中分享的好例子后,我发现我做错了,需要以相反的顺序进行。 从每个广播对象中获取电影,使用Movie.addBroadcast将广播添加到电影中并将其保存在数据存储区中,这就是我所做的,并且它工作正常。

非常感谢大家的帮助,我希望这会有助于其他人。

答案 2 :(得分:0)

GAE JDO有足够的code samplesassociated persistence code适用于所有类型的关系(包括拥有的1-N bidir)。

交易完成后你有一些“同花顺”,我不确定。您没有与电影和广播对象相关的代码(即Movie.addBroadcast在哪里?)。您根本不参考日志(它告诉您有关数据存储区的所有PUT和GET)。你说你正在检索一部电影并“保存它覆盖相同的id”,但没有代码可以做到这一点,或者提到当时对象所处的状态......瞬态?分离