【问题标题】:Using one-to-many owned relationship in JDO - AppEngine在 JDO 中使用一对多拥有关系 - AppEngine
【发布时间】:2013-03-09 14:49:48
【问题描述】:

我是 JDO 及其概念的新手。我之前使用过 ORMLite,这非常简单,我不知道我应该如何在 JDO 中做我在 ORMLite 中所做的事情。 我有 2 个实体,BroadcastMovie。每个Broadcast 有一个Movie,一个Movie 可以有多个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,所以我将BroadcastMovie 对象一起保存在其中并进行事务处理(因为是两个被保存的对象,所以这一定是原子动作):

// 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?

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • 我把两个类的id都改成了com.google.appengine.api.datastore.Key,可惜还是不行。我试图删除保留电影的部分,只保留其中包含电影对象的持久广播部分,并且由于某种原因电影没有添加到数据库中。
    【解决方案2】:

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

    感谢大家的帮助,我希望这对其他人有所帮助。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 我很抱歉缺少信息。我解决了这个问题,我现在发布所有信息的答案,所以它可能会帮助其他面临同样问题的人。
      猜你喜欢
      • 2011-08-24
      • 1970-01-01
      • 2013-04-17
      • 1970-01-01
      • 1970-01-01
      • 2010-12-30
      • 1970-01-01
      • 1970-01-01
      • 2013-11-11
      相关资源
      最近更新 更多