簡體   English   中英

Grails MongoDB插件如何處理多態?

[英]How does Grails MongoDB plugin handle polymorphism?

我有一個類似以下的對象:

class User {
    static mapWith="mongo"
    static embedded = [ 'profiles' ]

    String email
    List<Profile> profiles;
}

interface Profile {
}

class Profile1 implements Profile {
}

class Profile2 implements Profile {
}

如果我將具體的類Profile1或Profile2添加到User對象並將其保存到數據庫,則從MongoDB中讀回該對象時會引發異常。 在這種情況下,我看不到任何信息會保存到數據庫中以標識應實例化的對象類型。 確切地有關於該案件如何處理的零文檔。 其他框架具有處理此問題的機制,因此Grails MongoDB被嚴重破壞了,或者(再次)未作記錄。 那么我該如何解決呢?

例外情況如下:

| Error 2013-06-12 18:48:00,390 [http-bio-8080-exec-5] ERROR errors.GrailsExceptionResolver  - InstantiationException occurred when processing request: [POST] /mpa/user/authenticate -parameters:

  email: carhubb@gmail.com
  password: ***
  com.mycompany.security.Profile. Stacktrace follows:
  Message: com.mycompany.security.Profile
  Line | Method
  ->>  342 | newInstance0                        in java.lang.Class
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
  |    310 | newInstance                         in     ''

Grails MongoDB完全沒有損壞,每個用例都可能沒有記錄在案。 :)
您的用例可以按預期工作,並且如下所示已成功測試。

// src/groovy
interface Profile {
    Integer getDuration()
}

import org.bson.types.ObjectId
class Profile1 implements Profile {
    ObjectId id
    String profileName
    String type
    Date effectiveStartDate
    Date effectiveEndDate

    Integer getDuration(){
        effectiveEndDate - effectiveStartDate
    }

    static mapWith = "mongo"
}

import org.bson.types.ObjectId
class Profile2 implements Profile{
    ObjectId id
    String profileName
    String type
    Date effectiveStartDate
    Date effectiveEndDate

    static mapWith = "mongo"

    Integer getDuration(){
        effectiveEndDate - effectiveStartDate
    }
}
class User {
    ObjectId id

    static mapWith = "mongo"
    static embedded = ['profiles']

    String email
    List<Profile> profiles
}

class UserController {

    def index() {
        def profile1 = new Profile1(type: 'Individual',
                                    profileName: 'IndividualProfile',
                                    effectiveStartDate: new Date(),
                                    effectiveEndDate: new Date() + 100) as Profile
        def profile2 = new Profile2(type: 'Company',
                                    profileName: 'CompanyProfile',
                                    effectiveStartDate: new Date(),
                                    effectiveEndDate: new Date() + 50) as Profile

        println profile1.duration //prints 100
        println profile2.duration //prints 50

        def user = new User(profiles: [profile1, profile2], email: 'abc@gmail.com').save(flush: true)

        render user as JSON
    }
}

//db.user.find()
{ 
    "_id" : ObjectId("51ba8d55892cb98368b2f1e5"), 
    "email" : "abc@gmail.com", 
    "profiles" : [{   
            "effectiveEndDate" : ISODate("2013-09-22T03:26:13.396Z"),   
            "effectiveStartDate" : ISODate("2013-06-14T03:26:13.396Z"),   
            "profileName" : "IndividualProfile",    
            "type" : "Individual" 
        },
        {   
            "effectiveEndDate" : ISODate("2013-08-03T03:26:13.423Z"),       
            "effectiveStartDate" : ISODate("2013-06-14T03:26:13.423Z"),   
            "profileName" : "CompanyProfile",
            "type" : "Company" 
        } 
    ], 
    "version" : 0 
}

您也可以在此處找到上述設置。

注意:-為了簡化用法, Profile1Profile2的設計相似。

實際的答案是,grails似乎處理類而不是接口,這確實是奇怪的,因為如果您為類處理多態,那么為接口處理它是微不足道的,因為您可以以相同的方式處理它。 但是,如果您將類用於所有引用類型,它將在mongodb中添加一個特殊的'_class'屬性,並將使用該屬性實例化實際引用的對象(該對象在保存時指向該對象)。 現在,要用一個段落解釋而不是瀏覽源代碼和單元測試頁面有多難?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM