Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Data MongoDb for class inheritance

I want to store different data to one collection in MongoDb and have Spring data beans with appropriate field..

Sorry, I've skipped details.

Parent bean:

class A
    int a

Childs:

class B extends A
    double b

class C extends A
    String c

So, there is following document in mongo

{a : 1, b : 2.3, c : "Test"}

When I fetch data, it is ok. But, when I call save method from CrudRepository for B, it rewrites all data and I lose C.

I know only one good option to create custom save method with incremental updates, such as

update.set("b", newvalue)...

but with reflection.

Do you have any other ideas?

Thanks in advance.

like image 713
Pavel Drobushevich Avatar asked Jan 09 '12 19:01

Pavel Drobushevich


1 Answers

For Spring-data MongoTemplate, in additional to the fields in your object, an additional field name _class is also saved which tells the template which class it is saving.
You will not be able to save an object correctly using another object's repository, regardless of the inheritance relationship.

The CrudRepository for Spring is essentially the Generic Dao pattern. Since all your dao implement the interface, and have the save method, you will be able to save any of the object by knowing which dao to use.

To do this, you can create a RepositoryFactory which is used to initial your repository, which offers an getRepository(Class<?> type) function that provide you with the appropriate repository for your class. Then you will be able to do something like:

repositoryFactory.getRepository(myType.getClass()).save(myType);

You can find more detail here: https://web.archive.org/web/20160722023804/http://www.rainydayinn.com:80/dev/dao-factory-and-generic-dao-wiring-in-spring/

If you want to store all your objects in the same collection, you can use the annotation @Document (collection="mycollection"). If you do not give a collection name, the default is to save each class in a separate collection according to the class name.

like image 117
ltfishie Avatar answered Oct 16 '22 17:10

ltfishie