2013-03-09 51 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