James Gan
James Gan

Reputation: 7116

Which Java ORM framework support polymorphism of document in MongoDB?

I'm trying to use MongoDB to store a series of documents. These document share some standard attributes while it has several variation. We implement the POJO with an inheritance. The base class is Document, while it has several sub-classes such as Invoice and Orders, which has several additional fields when compared with Document class.

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

Is there an ORM framework support query the collection and return a list of mixed objects (invoice, order, basic document, etc) according to its type field?

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

Thanks a lot!

Upvotes: 2

Views: 1075

Answers (4)

Ivan Hristov
Ivan Hristov

Reputation: 3186

Another option is to use Jongo which delegates polymorphic handling to Jackson. I've wrote a blog post with some examples and you can find the full code base on GitHub.

In your specific scenario, your solution with Jackson will look like this:

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;
    }
}

Upvotes: 0

Yanjiong Wang
Yanjiong Wang

Reputation: 229

BuguMongo? http://code.google.com/p/bugumongo

Upvotes: 0

Remon van Vliet
Remon van Vliet

Reputation: 18615

Morhia supports polymorphism even without requiring a type enum or anything. It stores the actual instance classname along with the rest of the data. Have a look at the @Polymorphic annotation.

Upvotes: 3

Sumit Bisht
Sumit Bisht

Reputation: 1517

You can use just any ORM that supports the desired database dialect. The hibernate framework has Object/grid Mapper (OGM) subproject that does just this.

Upvotes: 1

Related Questions