2012-04-20 43 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; 
    } 
}