11

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.

5
  • 1
    Would you mind being a bit more verbose on the interaction with MongoTemplate and your repository? Are you reading the data back in into an object of B? That should in actually return an object of type C as we should detect the stored type information. Beyond that the collection mapping information would be helpful. Make sure all classes are mapped to the same collection. Commented Jan 10, 2012 at 8:16
  • Hi Oliver, thank you for your answer. Yes, I've override 'save' method of 'MongoTemplate' to use update query. Now when I save 'B', it updates only 'B' fields. But I try to find more awesome solution... Commented Jan 10, 2012 at 20:14
  • If you add the relevant code snippets we might dive into the issue a bit more :) Commented Jan 11, 2012 at 8:24
  • 1
    Hi Oliver, sorry for delay response. There is our solution: gist.github.com/1631780 Commented Jan 18, 2012 at 7:32
  • @OliverGierke thanks for all the hard work! 1.0.1.RELEASE fixed many issue for me Commented Feb 18, 2012 at 15:56

2 Answers 2

8

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.

Sign up to request clarification or add additional context in comments.

1 Comment

The URL given here is no longer valid! Please make the effort to point to a relevant one instead.
0

I also had the same problem, I solved it by adding the default constructor in the derived class and using specific repositories for each derived class..

public interface ClassBRepository extends MongoRepository<ClassBRepository , String> { 

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.