Type:Note
--- Intro ---
我們在 GAE Toturial 可以看到 Relastionship 的設置Owned One/One, One/Many
Unowned One/One, One/Many, Many/Many
這篇要講在設計上, 用 One/Many
但使用上, 卻常常要從 child 去找 parent
例如, 一個網站上的一個使用者, 他可能擁有多個 email
該怎麼 declare entities
--- Content ---
考慮下述 entities@PersistenceCapable(identityType = IdentityType.APPLICATION) public class MyUser implements java.io.Serializable { @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) private Key key; @Persistent private Date createDate; @Persistent private String name; @Persistent(mappedBy = "relUser") private Set在設計 entity 時, 宣告 變數的那個, 視為 parentrelSetUserEMail = new HashSet ();//one/many } @PersistenceCapable(identityType = IdentityType.APPLICATION) public class MyUserEMail implements java.io.Serializable { @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) private Key key;//(*1) @Persistent//(*1) private String email; @Persistent private Date createDate; @Persistent private String emailType; @Persistent private MyUser relUser;//one/one }
我們宣告 MyUser(parent)/MyUserEMail(child) : one/many
然後為了讓 child 可以方便找到 parent 又宣告了 MyUserEMail(parent)/MyUser(child) : one/many
再宣告 mappedBy = "relUser" 告知其相對應的欄位
我想討論一下一個狀況, 如果我們執行下述代碼
pm.currentTransaction().begin(); user = new MyUser(nowTime); user.setName(userService.getCurrentUser().getNickname()); pm.makePersistent(user); userEMail = new MyUserEMail(nowTime); userEMail.setEmail(email); user.getRelSetUserEMail().add(userEMail); pm.makePersistent(user);這是可以完成工作的
我們丟了一個 child 給 parent 認養
並且設定了 MyUserEMial.relUser 為相對應的欄位
但有件事要注意一下,
使用 PersistenceManager 是不允許變更 Parent, 所以一旦被丟到資料庫裡就不能變動了
而且一定要先 make(makePersistent) Parent
所以, 如果你把 (*1) 那2行註解掉
也就是用 "非自動產生" 的 DataType 作為 identity
那麼代碼怎麼改都沒法進資料庫
1. 用上述代碼 - 先 setEmail, add(userEMail) 再 makePersistent(user)
會出現 "MyUserEMail(xxxxx) has already been persisted without a parent" 的錯誤訊息
應該是因為email為key, 設置時就會被送到資料庫做驗證
2. 先 add(userEMail), makePersistent(user) 再 setEmail
會產生 "Cannot have a null primary key field"
所以, 大概只能用 Unowned Relationship
另外是, 若 要用 Owned Relationship, 則 entity 的 PK 必須為 Key
沒有留言:
張貼留言