Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot - MongoDB - Inheritance

I'm running into something odd with inheritance and mongodbrepositories.

I have the following:

`

@Document
public class Base {
    public String fieldA;
}

public class Derived extends Base {
    public String fieldB;
}

public interface DerivedRepository extends MongoRepository<Base, String> {
    List<Derived> findByFieldA(String fieldA);
}

`

When inserting i get

Inserting DBObject containing fields: [_class, _id, fieldA, fieldB ] in collection: base

When i do findByFieldA('some value') on the repository i get the following:

find using query: { "fieldA" : "some value" } fields: null for class: class Derived in collection: derived

Any idea what is going on here? And how can I fix this, either by saving it to the proper derived collection or by querying from the base collection.

Regards,

like image 697
Morrowyn Avatar asked Feb 07 '18 21:02

Morrowyn


People also ask

Does spring spring support MongoDB?

Spring also provides connectors like MongoTemplate and MongoRepository to perform all the database operations in MongoDB. What is Spring Boot used for? Spring Boot framework is used to create production-ready web applications with default configurations.

What is Mongo repository in Spring Boot?

MongoRepository — MongoRepository is used for basic queries that involve all or many fields of the document. Examples include data creation, viewing documents, and more. Spring Boot MongoDB configuration using both approaches needs only a few lines of code. Spring is an application framework for Java web applications.

How do I change the name of a spring data MongoDB class?

Spring Data MongoDB maps the Customer class into a collection called customer. If you want to change the name of the collection, you can use Spring Data MongoDB’s @Document annotation on the class.

What getters and setters are left out of spring data MongoDB?

In this guide, the typical getters and setters have been left out for brevity. id fits the standard name for a MongoDB ID, so it does not require any special annotation to tag it for Spring Data MongoDB. The other two properties, firstName and lastName, are left unannotated.


1 Answers

First, I would make Derived class as document since the parent is going to be shared among many implementations.

public class Base {
    public String fieldA;
}

@Document
public class Derived extends Base {
    public String fieldB;

    @Override
    public String toString() {
        return "{fieldA: " + getFieldA() + ", fieldB: " + fieldB + "}";
    }
}

Second, change the repository specification with the type of document (class marked as @Document) as:

public interface DerivedRepository extends MongoRepository<Derived, String> {
    List<Derived> findByFieldA(String fieldA);
    List<Derived> findByFieldB(String fieldB);
}

I added extra method findByFieldB(String fieldB) to explain more.

With these changes, you should be able to query either with fieldA or fieldB as below:

public class SpringBootMongoApplication {
    @Autowired
    private DerivedRepository derivedRepository;

    public void testMethod() throws Exception {
        Derived derived1 = new Derived();
        derived1.setFieldB("fieldB1");
        derived1.setFieldA("fieldA1");

        Derived derived2 = new Derived();
        derived2.setFieldB("fieldB2");
        derived2.setFieldA("fieldA2");
        this.derivedRepository.save(Arrays.asList(derived1, derived2));

        List<Derived> deriveds = this.derivedRepository.findByFieldA("fieldA1");
        System.out.println(deriveds);

        List<Derived> deriveds1 = this.derivedRepository.findByFieldB("fieldB2");
        System.out.println(deriveds1);
    }
}

The output should be:

[{fieldA: fieldA1, fieldB: fieldB1}]
[{fieldA: fieldA2, fieldB: fieldB2}]

You can also verify the object persisted and their types with mongo query as below: enter image description here

I have created an Spring Boot sample app which you can find in Github.

like image 155
Yogen Rai Avatar answered Nov 15 '22 09:11

Yogen Rai