2012-04-20 74 views
2

我試圖使用MongoDB來存儲一系列文檔。這些文檔共享一些標準屬性,但它有幾個變體。我們用繼承來實現POJO。基類是Document,但它有幾個子類,例如Invoice和Orders,與Document類相比有幾個附加字段。哪個Java ORM框架支持MongoDB中文檔的多態性?

class Document { 
    DocTypeEnum type; 
    String title; 
} 
class Invoice extends Document{ 
    Date dueDate; 
} 
class Order extends Document{ 
    List<LineItems> items; 
} 

是否有ORM框架支持查詢集合並根據其類型字段返回混合對象(發票,訂單,基本文檔等)的列表?

List<Document> results = DocCollection.find(...); 

非常感謝!

回答

3

Morhia支持多態,即使不需要類型枚舉或任何東西。它存儲實際的實例類名以及其餘的數據。看看@Polymorphic註解。

+0

感謝您指出的精彩多態性註釋。另外,我注意到它是Morhia支持的內置,即使沒有Polymorphic註釋,請參閱:http://www.carfey.com/blog/using-mongodb-with-morphia/ – 2012-04-21 03:07:08

1

您可以使用任何支持所需數據庫方言的ORM。 休眠框架有Object/grid Mapper(OGM)子項目,只是這樣做。

0

另一種選擇是使用Jongo,其將多態處理委託給Jackson。我已經寫了blog post的一些例子,你可以在GitHub找到完整的代碼庫。

在您的具體方案,與傑克遜的解決方案將是這樣的:

public enum DocTypeEnum { 
    INVOICE(Constants.INVOICE), ORDER(Constants.ORDER); 

    DocTypeEnum(String docTypeString) { 
    } 

    public static class Constants { 
     public static final String INVOICE = "INVOICE"; 
     public static final String ORDER = "ORDER"; 
    } 
} 

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, 
property = Document.TYPE) 
@JsonSubTypes({ 
    @JsonSubTypes.Type(value = Invoice.class, name = DocTypeEnum.Constants.INVOICE), 
    @JsonSubTypes.Type(value = Order.class, name = DocTypeEnum.Constants.ORDER) 
}) 
public class Document { 

    public static final String TYPE = "type"; 
    public static final String TITLE = "title"; 

    private final DocTypeEnum type; 
    private final String title; 

    public Document(DocTypeEnum type, String title) { 
     this.type = type; 
     this.title = title; 
    } 

    @JsonProperty(TYPE) 
    public DocTypeEnum getType() { 
     return type; 
    } 

    @JsonProperty(TITLE) 
    public String getTitle() { 
     return title; 
    } 
} 

@JsonIgnoreProperties(ignoreUnknown = true) 
public class Invoice extends Document { 
    public static final String DUE_DATE = "due_date"; 
    private final Date dueDate; 

    public Invoice(String title, Date dueDate) { 
     super(DocTypeEnum.INVOICE, title); 
     this.dueDate = dueDate; 
    } 

    @JsonProperty(DUE_DATE) 
    public Date getDueDate() { 
     return dueDate; 
    } 
} 

@JsonIgnoreProperties(ignoreUnknown = true) 
public class Order extends Document { 

    public static final String ITEMS = "items"; 
    private final List<LineItems> items; 

    public Order(String title, List<LineItems> items) { 
     super(DocTypeEnum.ORDER, title); 
     this.items = items; 
    } 

    @JsonProperty(ITEMS) 
    public List<LineItems> getItems() { 
     return items; 
    } 
}