How to write custom query in Mongo Spring Data JPA - spring

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.stereotype.Repository;
#Repository
public interface PersonRepository extends MongoRepository<Person, String> {
#Query("{ 'firstname' : ?0 }")
List<Person> findByFirstname(String firstname);
}
I am using spring data jpa with MongoDB. I am able to save, delete or retrieve (all records) using repository.
I am trying to retrieve record based on a property value. (Custom Query shown above). This does not work.
Can someone help me in finding out how to write custom Queries in MongoRepository where I can pass a column value and get the matching rows.
EDIT:
Adding Code.
#Document/*(collection = "person")*/
public class Person {
#Id
private String id;
private String firstName;
private String lastName;
private Address address;
// gettters and setters
}
#Service
public class PersonServiceImpl{
#Autowired
private PersonRepository personRepository;
public Person findPersonByFirstName(String firstName) {
List<Person> person = personRepository.findAllByFirstName(firstName);
System.out.println("** Data Retrieved **" );
return person.get(0);
}
}

You don't need a custom query for this kind of query.
Following should just work (provided your field in Person class is "firstname" - is that righ?)
List<Person> findAllByFirstname(String firstname);
Does your query work from a mongo console?

Related

Spring Boot JPA returns correct count but no data

Evening,
I have a Spring application that is connected to a PostgresSQL db. I can connect to the database and see that the query is returning the correct number of elements for the array but nothing in them:
curl http://localhost:8080/books
[{},{},{}]%
My Book model looks like this:
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.math.BigDecimal;
#Entity
public class Book {
#Id
#GeneratedValue
private Long id;
private String name;
private String author;
private BigDecimal price;
public Book() {}
public Book(String name, String author, BigDecimal price) {
this.name = name;
this.author = author;
this.price = price;
}
}
and the controller:
#RestController
public class BookController {
#Autowired
private BookRepository repository;
// Find
#GetMapping("/books")
List<Book> findAll() {
List<Book> books = repository.findAll();
System.out.println(books);
return repository.findAll();
}
}
I've looked at these questions here, here and here but those answers didn't fit with this.
What am I not doing to see data come back?
In order for your entity to be serialized by Spring the entity needs to have getters for its properties. You could use lombok to auto-generate getter/setters for you entity properties or just write them your own.

No converter found capable of converting from type to type

I am getting the following stacktrace:
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [referencedata.ABDeadlineType] to type [referencedata.DeadlineType]
at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:324)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:206)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:187)
at org.springframework.data.repository.query.ResultProcessor$ProjectingConverter.convert(ResultProcessor.java:256)
at org.springframework.data.repository.query.ResultProcessor$ChainingConverter$1.convert(ResultProcessor.java:201)
at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:212)
at org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:149)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:121)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:106)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:483)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:461)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy143.findAllSummarizedBy(Unknown Source)
at
My classes are the following
DeadlineType
#Data
public class DeadlineType extends DefaultIdAndText {
#Value("#{target.id}")
String id;
#Value("#{target.code}")
String text;
#Value("#{target.id}")
public String getId() {
return id;
}
#Value("#{target.code}")
public String getText() {
return text;
}
}
ABDeadlineType
#Data
#Entity
#Table(name = "deadline_type")
#AllArgsConstructor
#NoArgsConstructor
public class ABDeadlineType {
private #Id
String id;
private String code;
}
DefaultIdAndText
#Data #AllArgsConstructor
#NoArgsConstructor
public class DefaultIdAndText implements IdAndText {
public DefaultIdAndText(IdAndText idAndText){
this.id = idAndText.getId();
this.text = idAndText.getText();
}
#NotEmpty String id;
String text;
}
DeadlineTypeRepository
public interface DeadlineTypeRepository extends JpaRepository<ABDeadlineType, Long> {
List<DeadlineType> findAllSummarizedBy();
}
Update
Could it be an issue that the projection/mapping using #Value("#{target.id}") format, does not work correctly because these have been done on a class and not on an interface???
Return ABDeadlineType from repository:
public interface ABDeadlineTypeRepository extends JpaRepository<ABDeadlineType, Long> {
List<ABDeadlineType> findAllSummarizedBy();
}
and then convert to DeadlineType. Manually or use mapstruct.
Or call constructor from #Query annotation:
public interface DeadlineTypeRepository extends JpaRepository<ABDeadlineType, Long> {
#Query("select new package.DeadlineType(a.id, a.code) from ABDeadlineType a ")
List<DeadlineType> findAllSummarizedBy();
}
Or use #Projection:
#Projection(name = "deadline", types = { ABDeadlineType.class })
public interface DeadlineType {
#Value("#{target.id}")
String getId();
#Value("#{target.code}")
String getText();
}
Update:
Spring can work without #Projection annotation:
public interface DeadlineType {
String getId();
String getText();
}
You may already have this working, but the I created a test project with the classes below allowing you to retrieve the data into an entity, projection or dto.
Projection - this will return the code column twice, once named code and also named text (for example only). As you say above, you don't need the #Projection annotation
import org.springframework.beans.factory.annotation.Value;
public interface DeadlineTypeProjection {
String getId();
// can get code and or change name of getter below
String getCode();
// Points to the code attribute of entity class
#Value(value = "#{target.code}")
String getText();
}
DTO class - not sure why this was inheriting from your base class and then redefining the attributes. JsonProperty just an example of how you'd change the name of the field passed back to a REST end point
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
#Data
#AllArgsConstructor
public class DeadlineType {
String id;
// Use this annotation if you need to change the name of the property that is passed back from controller
// Needs to be called code to be used in Repository
#JsonProperty(value = "text")
String code;
}
Entity class
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Data
#Entity
#Table(name = "deadline_type")
public class ABDeadlineType {
#Id
private String id;
private String code;
}
Repository - your repository extends JpaRepository<ABDeadlineType, Long> but the Id is a String, so updated below to JpaRepository<ABDeadlineType, String>
import com.example.demo.entity.ABDeadlineType;
import com.example.demo.projection.DeadlineTypeProjection;
import com.example.demo.transfer.DeadlineType;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface ABDeadlineTypeRepository extends JpaRepository<ABDeadlineType, String> {
List<ABDeadlineType> findAll();
List<DeadlineType> findAllDtoBy();
List<DeadlineTypeProjection> findAllProjectionBy();
}
Example Controller - accesses the repository directly to simplify code
#RequestMapping(value = "deadlinetype")
#RestController
public class DeadlineTypeController {
private final ABDeadlineTypeRepository abDeadlineTypeRepository;
#Autowired
public DeadlineTypeController(ABDeadlineTypeRepository abDeadlineTypeRepository) {
this.abDeadlineTypeRepository = abDeadlineTypeRepository;
}
#GetMapping(value = "/list")
public ResponseEntity<List<ABDeadlineType>> list() {
List<ABDeadlineType> types = abDeadlineTypeRepository.findAll();
return ResponseEntity.ok(types);
}
#GetMapping(value = "/listdto")
public ResponseEntity<List<DeadlineType>> listDto() {
List<DeadlineType> types = abDeadlineTypeRepository.findAllDtoBy();
return ResponseEntity.ok(types);
}
#GetMapping(value = "/listprojection")
public ResponseEntity<List<DeadlineTypeProjection>> listProjection() {
List<DeadlineTypeProjection> types = abDeadlineTypeRepository.findAllProjectionBy();
return ResponseEntity.ok(types);
}
}
Hope that helps
Les
I have met the same problem recently with spring-data-jpa:2.5.0.
Solution (for queries with no #Query annotation):
For class-based projection (DTOs), the problem is the #NoArgsConstructor in the DTO class. Revemoving it should make things work.
Something interesting I found during debug:
With the presence of a non argument constructor, the returnedType somehow was created with 0 input properties.
When a query is actually created, JpaQueryCreator (spring-data-jpa) would check if it needs to do custom construction according to the number of input properties.
As it's not the case with 0 input properties, it would then return the whole entity instance.
https://github.com/spring-projects/spring-data-jpa/blob/main/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java#L169
Finally when the result is being returned, the target type and returned type don't match, as there is no converter available to convert from the entity instance to the projectiong dto. The error was thrown.
https://github.com/spring-projects/spring-data-commons/blob/main/src/main/java/org/springframework/data/repository/query/ResultProcessor.java#L162
Simple Solution::
use {nativeQuery=true} in your query.
for example
#Query(value = "select d.id,d.name,d.breed,d.origin from Dog d",nativeQuery = true)
List<Dog> findALL();
If you look at the exception stack trace it says that, it failed to convert from ABDeadlineType to DeadlineType. Because your repository is going to return you the objects of ABDeadlineType. How the spring-data-jpa will convert into the other one(DeadlineType). You should return the same type from repository and then have some intermediate util class to convert it into your model class.
public interface ABDeadlineTypeRepository extends JpaRepository<ABDeadlineType, Long> {
List<ABDeadlineType> findAllSummarizedBy();
}
Turns out, when the table name is different than the model name, you have to change the annotations to:
#Entity
#Table(name = "table_name")
class WhateverNameYouWant {
...
Instead of simply using the #Entity annotation.
What was weird for me, is that the class it was trying to convert to didn't exist. This worked for me.
Well I have another answer I have used Interfaces for Projections and Classes for
Dto's and I am using ModelMapper to map my Projections to Dto Class
So my 1 Dto class may have many Projections which can mapped to Dto and used to Taste
gradle
implementation 'org.modelmapper:modelmapper:3.1.0'
#Autowired
private ModelMapper modelMapper;
List<UserDto> usersdto = repository.findUserByRoleName().stream().map(userprojection -> modelMapper.map(userprojection, UserDto.class))
.collect(Collectors.toList());
My projection is like this
public interface UserProjection {
String getId();
String getEmail();
}
My dto is
#Data
#AllArgsConstructor
#NoArgsConstructor
public class UserDto {
private long id;
private String firstName;
private String lastName;
private String phone;
private String email;
}
And I am able to get fields from custom queries
Change the class name to DeadlineType inside
extends JpaRepository<class, type>
For example:
In your code, the repository where you placed you query extends JpaRepository that with class and id type <ABDeadlineType, Long>. So it expects to return ABDeadlineType data.
public interface DeadlineTypeRepository extends JpaRepository<ABDeadlineType, Long> {
List<DeadlineType> findAllSummarizedBy();
}
As you want to get DeadlineType data, you should keep your query in such repository like
public interface DeadlineTypeRepository extends JpaRepository<DeadlineType, Long>
So, either replace the class name inside JpaRepository<>
Or place your query in another repository. Then you don't need to do any mapping or write extra codes for it.
In my case, it worked.

How to fetch only selected attributes of an entity using Spring JPA?

I'm using Spring Boot (1.3.3.RELEASE) and Hibernate JPA in my project. My entity looks like this:
#Data
#NoArgsConstructor
#Entity
#Table(name = "rule")
public class RuleVO {
#Id
#GeneratedValue
private Long id;
#Column(name = "name", length = 128, nullable = false, unique = true)
private String name;
#Column(name = "tag", length = 256)
private String tag;
#OneToMany(mappedBy = "rule", cascade = CascadeType.ALL, orphanRemoval = true)
private List<RuleOutputArticleVO> outputArticles;
#OneToMany(mappedBy = "rule", cascade = CascadeType.ALL, orphanRemoval = true)
private List<RuleInputArticleVO> inputArticles;
}
My repository looks like this:
#Repository
public interface RuleRepository extends JpaRepository<RuleVO, Long> {
}
In some cases I need to fetch only id and name attributes of entity RuleVO. How can I achieve this? I found a notice it should be doable using Criteria API and Projections but how? Many thanks in advance. Vojtech
UPDATE:
As has been pointed out to me, I'm lazy and this can very well be done hence I'm updating my answer after having looked around the web for a proper one.
Here's an example of how to get only the id's and only the names:
#Repository
public interface RuleRepository extends JpaRepository<RuleVO, Long> {
#Query("SELECT r.id FROM RuleVo r where r.name = :name")
List<Long> findIdByName(#Param("name") String name);
#Query("SELECT r.name FROM RuleVo r where r.id = :id")
String findNameById(#Param("id") Long id);
}
Hopefully this update proves helpful
Old Answer:
Only retrieving the specific attributes name/id is not possible as this is not how spring was designed or any SQL database for that matter as you always select a row which is an entity.
What you CAN do is query over the variables in the entity, for instance:
#Repository
public interface RuleRepository extends JpaRepository<RuleVO, Long> {
public RuleVo findOneByName(String name);
public RuleVo findOneByNameOrId(String name, Long id);
public List<RuleVo> findAllByName(String name);
// etc, depending on what you want
}
You can modify these however you want w.r.t. your needs. You can call these methods directly via the autowired repository
See http://docs.spring.io/spring-data/jpa/docs/current/reference/html/ Section 5.3 for more options and examples
interface IdOnly{
String getId();
}
#Repository
public interface RuleRepository extends JpaRepository<RuleVO, Long> {
public List<IdOnly> findAllByName(String name);
}
I notice that this is a very old post, but if someone is still looking for an answer, try this. It worked for me.
You can also define custom constructor to fetch specific columns using JPQL.
Example:
Replace {javaPackagePath} with complete java package path of the class
use as a constructor in JPQL.
public class RuleVO {
public RuleVO(Long id, String name) {
this.id = id;
this.name = name;
}
}
#Repository
public interface RuleRepository extends JpaRepository<RuleVO, Long> {
#Query("SELECT new {javaPackagePath}.RuleVO(r.id, r.name) FROM RuleVo r where r.name = :name")
List<RuleVO> findIdByName(#Param("name") String name);
}
Yes, you can achieve it with projections. You have many ways to apply them:
If you could upgrade to Spring Data Hopper, it provides an easy to use support for projections. See how to use them in the reference documentation.
Otherwise, first of all create a DTO with the attributes you want to load, something like:
package org.example;
public class RuleProjection {
private final Long id;
private final String name;
public RuleProjection(Long id, String name) {
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
}
Of course, you could use Lombok annotations also.
Then, you can use in the JPQL queries like this:
select new org.example.RuleProjection(rule.id, rule.name) from RuleVO rule order by rule.name
Another option, if you want to avoid using DTO class names in your queries, is to implement your own query method using QueryDSL. With Spring Data JPA, you have to:
Create a new interface with the new method. Ex:
public interface RuleRepositoryCustom {
public List<RuleProjection> findAllWithProjection();
}
Change your repository to extend the new interface. Ex:
public interface RuleRepository extends JpaRepository<RuleVO, Long>, RuleRepositoryCustom {
...
Create an implementation of the Custom repository using the Spring Data JPA QueryDSL support. You have to previously generate the Q clases of QueryDSL, using its Maven plugin. Ex:
public class RuleRepositoryImpl {
public List<RuleProjection> findAllWithProjection() {
QRuleVO rule = QRuleVO.ruleVO;
JPQLQuery query = getQueryFrom(rule);
query.orderBy(rule.name.asc());
return query.list(ConstructorExpression.create(RuleProjection.class, rule.id, rule.name));
}
}
You can do it by using #Query annotation(HQL).
Please refer to the Spring docs below:
http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.at-query
(search for #Query in spring document)

Select one column using Spring Data JPA

Does anyone have any idea how to get a single column using Spring Data JPA? I created a repository like below in my Spring Boot project, but always get the {"cause":null,"message":"PersistentEntity must not be null!"} error when accessing the Restful URL.
#RepositoryRestResource(collectionResourceRel = "users", path = "users")
public interface UsersRepository extends CrudRepository<Users, Integer> {
#Query("SELECT u.userName FROM Users u")
public List<String> getUserName();
}
Then if I access the Restful URL like ../users/search/getUserName, I get the error:
{"cause":null,"message":"PersistentEntity must not be null!"}
Create a Projection interface
public interface UserNameOnly {
String getUserName();
}
Then in your repository interface return that type instead of the user type
public interface UserRepository<User> extends JpaRepository<User,String> {
List<UsernameOnly> findNamesByUserNameNotNull();
}
The get method in the projection interface must match a get method of the defined type on the JPA repository, in this case User.
The "findBySomePropertyOnTheObjectThatIsNotNull" allows you to get a List of the entities (as opposed to an Iterable) based on some criteria, which for a findAll can simply be if the unique identifier (or any other NonNull field) is not null.
Concept is : In your entity class create a constructor with only required instant variables. And use that constructor in the repository method shown below.
Lets say you have a interface Repository like below
Repository implementation:
public interface UserRepository<User> extends JpaRepository<User,String>
{
#Query(value = "select new com.org.User(usr.userId) from User usr where usr.name(:name)")
List<User> findUserIdAlone(#Param("name") String user);
}
In Controller
#RestController
public class UserController
{
#Autowired
private UserRepository<User> userRepository;
#Res
public ResponseEntity<User> getUser(#PathVariable("usrname") String userName)
{
User resultUser = usrRepository.findUserIdAlone(userName);
return ResponseEntity.ok(resultUser);
}
}
public class User
{
private String userId,userName;
public User(String userId)
{
this.userId=userId;
}
// setter and getters goes here
}
This Works for me.
public interface UserDataRepository extends JpaRepository<UserData, Long> {
#Query(value = "SELECT emp_name FROM user_data", nativeQuery = true)
public List<Object[]> findEmp_name();
}
System.out.println("data"+ userDataRepository.findEmp_name());
The above line gave me this result :
data[abhijeet, abhijeet1, abhijeet2, abhijeet3, abhijeet4, abhijeet5]
If you want to only return a single column you should look at Projections and Excerpts which will allow you to filter specific columns and other things that are usefule.
If you need list all of the users, try select userName from Users, if you need one user use "where" look at spring data JPA http://docs.spring.io/spring-data/jpa/docs/current/reference/html/ , try change CrudRepository to JpaRepository
It is possible to provide custom implementations of methods in a Spring Data JPA repository, which enables complete control on queries and return types. The approach is as follows:
Define an interface with the desired method signatures.
Implement the interface to achieve the desired behavior.
Have the Repository extend both JpaRepository and the custom interface.
Here is a working example that uses JpaRepository, assuming a user_table with two columns, user_id and user_name.
UserEntity class in model package:
#Entity
#Table(name = "user_table")
public class UserEntity {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name = "user_id")
private Long userId;
#Column(name = "user_name")
private String userName;
protected UserEntity() {}
public UserEntity(String userName) {
this.userName = userName;
// standard getters and setters
}
Define interface for the custom repository in the repository package:
public interface UserCustomRepository {
List<String> findUserNames();
}
Provide implementation class for the custom interface in the repository package:
public class UserCustomRepositoryImpl implements UserCustomRepository {
// Spring auto configures a DataSource and JdbcTemplate
// based on the application.properties file. We can use
// autowiring to get a reference to it.
JdbcTemplate jdbcTemplate;
#Autowired
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
// Now our custom implementation can use the JdbcTemplate
// to perform JPQL queries and return basic datatypes.
#Override
public List<String> findUserNames() throws DataAccessException {
String sql = "SELECT user_name FROM user_table";
return jdbcTemplate.queryForList(sql, String.class);
}
}
Finally, we just need to have the UserRepository extend both JpaRepository and the custom interface we just implemented.
public interface UserRepository extends JpaRepository<UserEntity, Long>, UserCustomRepository {}
Simple test class with junit 5 (assuming the database is initially empty):
#SpringBootTest
class UserRepositoryTest {
private static final String JANE = "Jane";
private static final String JOE = "Joe";
#Autowired
UserRepository repo;
#Test
void shouldFindUserNames() {
UserEntity jane = new UserEntity(JANE);
UserEntity joe = new UserEntity(JOE);
repo.saveAndFlush(jane);
repo.saveAndFlush(joe);
List<UserEntity> users = repo.findAll();
assertEquals(2, users.size());
List<String> names = repo.findUserNames();
assertEquals(2, names.size());
assertTrue(names.contains(JANE));
assertTrue(names.contains(JOE));
}
}

Spring MongoRepository query adding _class field to queries

I have a domain class called User. It uses an object of MyUserId as the Id
#Document(collection = "users")
public class User implements Serializable {
#Property
#Id
private MyUserId id;
#Version
private Integer version;
private String firstName;
// Setters, getters
}
The MyUserId class:
public class MyUserId implements Serializable{
#Property
private String userId;
#Property
private String sampleId;
// setters, getters
}
Inside my Mongo, documents are getting stored as {_id:{userId:....., sampleId:....}, <more fields here>}
My userRepository is like this:
public interface UserRepository extends MongoRepository<User, MyUserId> {
#Query("{'_id': {$in: ?0}}")
List<User> findByUserIds(Collection<MyUserId> userIds);
}
When I'm querying my userRepository, The query is being fired as:
{_id: {$in: [ {_class:"com.sampleuser.MyUserId", userId:"....", sampleId:"...."}, {_class:"com.sampleuser.MyUserId", userId:"....", sampleId:"...."}]}}
It's obvious that it's adding the _class field while querying, but not while storing. Can someone throw some light at how to fix this? It's causing all my queries to fail. Thank you!
There actually exists an issue when using #Query whith complex id types. I'd suggest to use a custom repository implementation until DATAMONGO-1078 is resolved.
Within the custom implementation you could use MongoTemplate to execute the query somehow like this
#Override
public List<User> findByUserIds(Collection<MyUserId> userIds) {
return template.find(query(where("id").in(userIds)), User.class);
}

Resources