Spring Data Mongodb - repository for collection with different types

java, mongodb, spring, spring-data, spring-data-mongodb

Solution

If Node\LeafType1\LeafType2 are sub-classes of AbstractMyCollectionNode, then things will be easy. Just declare the repository like you write:

public interface MyCollectionRepository extends MongoRepository<AbstractMyCollectionNode, String> { }

We have done this in a project, and it works good. Spring Data will add an property named '_class' to the documents in mongodb collection, so that it can finger out which class to instantiate.

Documents that stored in one collection may have some similarity, maybe you can extract a generic class for them.

Here are some code copied from one of our projects:

Entity:

public abstract class Document {
    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
    ....
public class WebClipDocument extends Document {
    private String digest;
    ...

Repository:

public interface DocumentDao extends MongoRepository<Document, String>{
...

And, if your documents in mongodb collection does not have the "_class" property. You can use Converter:

When storing and querying your objects it is convenient to have a MongoConverter instance handle the mapping of all Java types to DBObjects. However, sometimes you may want the `MongoConverter’s do most of the work but allow you to selectively handle the conversion for a particular type or to optimize performance.

Problem

I have a mongo collection that may contain three types of entities that I map to java types: - Node - LeafType1 - LeafType2 Collection is ment to store tree-like structure using dbRefs of child nodes in parent entry. I didn't find any information about subject in Spring reference documentation so I'm asking here: Is there a way to use `Repository` mechanism to work with collection that may contain different types of objects? Declaring several repositories for different types in one collection seems like not very good idea because I always struggle with situations when queried object is not of expected type and creating one repository for abstract class that all possible types inherrit doesn't seems to work. To illustrate what I mean: ``` /** * This seems not safe */ public interface NodeRepository extends MongoRepository<Node, String> { } public interface LeafType1Repository extends MongoRepository<LeafType1, String> { } public interface LeafType2Repository extends MongoRepository<LeafType2, String> { } /** * This doesn't work at all */ public interface MyCollectionRepository extends MongoRepository<AbstractMyCollectionNode, String> { } ```

Original source