2014-05-12 74 views
1

在谷歌應用程序引擎的Java,谷歌的App Engine(Java)的數據庫自動生成的ID

當我這樣做:

ProjectData pd = new ProjectData(); 
pd.id = null; // let Objectify auto-generate the project id 
pd.dateCreated = date; 
datastore.put(pd); // put the project in the db so that it gets assigned an id 

數據庫會自動分配一個唯一的ID給每個PD,當運行「 datastore.put(PD)」。 不過,如果我添加父鍵字段:

ProjectData pd_new= new ProjectData(); 
pd_new.id = null; // let Objectify auto-generate the project id 
pd_new.parentKey= new Key<OtherData>(OtherData.class, anotherId); 
pd_new.dateCreated = date; 
datastore.put(pd_new); 

即使ID仍將是自動生成的,它不是唯一了。 ID總是一樣的。例如,我在數據庫7個ProjectData的,它們的ID都是「5629499534213120」

我的數據結構是

public class ProjectData { 
    @Id Long id; 
    @Parent Key<OtherData> parentKey; 
    long dataCreated; 
} 

難道我做錯了這裏,這個錯誤我好幾天。


BTW,我可以通過手動分配每個人

pd_new.id = System.currentTimeMillis(); 

的修復它,但我不認爲這是一個適當的方式做到這一點。

回答

1

這是正確的行爲。它爲什麼打擾你?

爲了使get()數據存儲中的實體,您需要創建它的密鑰。爲此,您需要一個父鍵和一個子實體ID。這使得這個鍵總是唯一的(父實體總是有不同的ID),即使其他父實體的子實體具有相同的ID。

+0

所以你的意思不是讓它自動生成,而是手動使用(父母,孩子)作爲關鍵,對不對?它仍然是一個很長的int ID?謝謝 – RobinBattle

+0

不,你應該使用自動生成的ID。當您想要檢索子實體的密鑰時,您需要知道子實體的密鑰,或者如果您知道子實體的ID及其父代的ID,則始終可以創建此密鑰。 –

3

添加更多詳情安德烈的回答是:

在AppEngine上,有5個部分組成的鍵,而且只有這5個部分共同所有鍵是保證唯一性的AppEngine:

  1. 您的應用的ID。
  2. 命名空間,用於多租戶應用程序。
  3. 實體類型名稱。
  4. 完整的祖先路徑。
  5. 此實體的ID。

因此,有可能爲不同類型的實體有相同的ID,而且,它也可能有相同類型的實體,但具有不同的祖先的路徑,以具有相同的ID。其中一個必然結果是,如果你有一個對象,但改變了它的父對象,它會創建一個全新的對象 - 它不會更新現有對象。因此,如果可以重新實體化實體,則不應將關係建模爲AppEngine中的父子關係。因此,如果您使用的是Objectify,我建議的一件事情是僅從您的對象公開KEY(可能是網絡安全字符串版本),而不是ID。另一個選項是使用字符串ID,但在保存之前使用UUID.randomUUID填充它。

+0

命名空間也是密鑰的一部分。 –

+1

感謝@PeterKnego,忘記了多租戶應用程序。編輯我的答案以添加命名空間。 – adevine