2013-03-09 50 views
1

我是JDO及其概念的新手。我之前和ORMLite一起工作非常简单,我不知道我应该如何在JDO中做我在ORMLite中做的事情。我有2个实体,BroadcastMovie。每Broadcast有一个MovieMovie可以有许多​​s。 广播的id不会生成,它在持久化之前配置。 所以这是我做过什么:在JDO中使用一对多的关系 - AppEngine

@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即提取并保存数据库中的所有数据。 首先,我获取所有​​,因为我知道的每一个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的引用。

但每当我查询DB的广播,并希望能找到在他们的电影引用了所有我得到的是空或此异常:

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? 

那么,我究竟错在这里做什么?

回答

1

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

非常感谢大家的帮助,我希望这可以帮助其他人。

1

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

+0

我将两个类的ID都更改为'com.google.appengine.api.datastore.Key',但不幸的是它仍然无法正常工作。我试图删除持续播放电影的部分,只留下电影对象持续播放的部分,并且由于某种原因电影不会添加到数据库中。 – Elad92 2013-03-09 17:27:35

0

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

交易完成后,您有一些“冲洗”,我不确定。您没有与Movie和Broadcast对象相关的代码(即Movie.addBroadcast在哪里?)。您根本不参考日志(它会告诉您有关数据存储的所有PUT和GET)。你说你正在检索一个电影,并“保存它覆盖相同的ID”,但没有代码可以做到这一点,或提到对象在那时的状态......瞬态?超脱?

+0

我很抱歉缺乏这方面的信息。我解决了这个问题,现在我发布了所有信息的答案,所以它可能会帮助其他人面对同样的问题。 – Elad92 2013-03-11 13:57:22