Invalid parameter index! You seem to have declared too little query method parameters - spring

I have an entity:
#Document(collection = "userData")
#Data
public class UserData {
#Id
#Field("_id")
private String id;
#Field("orderColumns")
private List<String> orderColumns;
#Field("ownerId")
private String ownerId;
}
And I have a repository:
#Repository
interface UserDataRepository extends MongoRepository<UserData, String> {
Optional<UserData> findByOwnerIdAndOrderColumnsExists(String ownerId);
}
When I execute this method, I get an exception:
Invalid parameter index! You seem to have declared too little query method parameters!

Related

How to exclude/disable #Entity Annotation for particular class

I want to disable #Entity Annotation for particular class.
Here is my sample code.
#Component
public class GenericDropDown{
private Integer id;
private String key;
private String value;
// Standard getter and setter
The above class is used for fetching data from multiple table for rendering different dropdown list from different tables.
How I can achieve this without #Entity Annotation
Here is my sample code.
#Component
public class GenericDropDown{
private Integer id;
private String key;
private String value;
// Standard getter and setter
#Repository
public class DropDownDao {
#Autowired
private EntityManager entityManager;
public Object runNativeQuery() {
#SuppressWarnings("unchecked")
List<Priority> o= entityManager.createNativeQuery("select Id,PRKEY,PRVALUE from Priority",Priority.class)
.getResultList();
return o;
}
}
**Error:**Unknown entity: com.min.test.Project.entity.Priority; nested exception is org.hibernate.MappingException: Unknown entity: com.min.test.Project.entity.Priority
You can select List of Objects array and map them yourself.
List<Object[]> o = entityManager.createNativeQuery("select Id,PRKEY,PRVALUE from Priority").getResltList();
List<MyClass> result = o.stream().map(arr -> new MyClass((Long) arr[0], (String) arr[1])).collect(Collectors.toList());
Or you also can use a JdbcTemplate instead of EntityManager:
#Autowired
private JdbcTemplate jdbcTemplate;
public List<MyClass> runQuery() {
String select = "select Id,yourParameterHere from Priority";
return jdbcTemplate.query(select, (rs, rowNum) -> new MyClass(rs.getLong("Id"), rs.getString("yourParameterHere")));
}

Instructing Sping Data MongoDB to use correct mapping between ObjectId and its class

I cannot retrieve the 2nd level nested objects in Spring Data MongoDB
I have nested collection in MongoDB to retrieve with Spring. Imagine this schema
#Data
#Builder
#Document(collection = "emitted")
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Emitter{
#Id
private String id;
#Field("installation")
#DocumentReference(lazy = true)
private Installaton installation;
// other fields
#Data
#Builder
#Document(collection = "installation")
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Installation {
#Id
private String id;
#Field("subject")
#DocumentReference(lazy = true)
private Subject subject;
// other fields
#Data
#Builder
#Document(collection = "subject")
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Subject {
#Id
private String id;
// other fields
Plus, I have MapStruct to map nested object field to string, for the purpose of avoiding cyclic reference introducing the search by id of the collection:
#ObjectFactory
public <T> T map(#NonNull final String id, #TargetType Class<T> type) {
return mongoTemplate.findById(id, type);
}
Everything works at first level, but at nested level I have this error:
Caused by: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.bson.types.ObjectId] to type [com.package.collections.Subject]
at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:322)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:195)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:175)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.doConvert(MappingMongoConverter.java:1826)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.doConvert(MappingMongoConverter.java:1818)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.getPotentiallyConvertedSimpleRead(MappingMongoConverter.java:1337)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.getPotentiallyConvertedSimpleRead(MappingMongoConverter.java:1311)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$DefaultConversionContext.convert(MappingMongoConverter.java:2371)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$ConversionContext.convert(MappingMongoConverter.java:2174)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1936)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readProperties(MappingMongoConverter.java:638)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.populateProperties(MappingMongoConverter.java:549)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:527)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readDocument(MappingMongoConverter.java:491)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:427)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:423)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:120)
at org.springframework.data.mongodb.core.MongoTemplate$ReadDocumentCallback.doWith(MongoTemplate.java:3326)
at org.springframework.data.mongodb.core.MongoTemplate.executeFindOneInternal(MongoTemplate.java:2940)
at org.springframework.data.mongodb.core.MongoTemplate.doFindOne(MongoTemplate.java:2618)
at org.springframework.data.mongodb.core.MongoTemplate.doFindOne(MongoTemplate.java:2588)
at org.springframework.data.mongodb.core.MongoTemplate.findById(MongoTemplate.java:922)
at com.package.myapp.services.mapper.ReferenceMapper.map(ReferenceMapper.java:26)
at com.package.myapp.services.mapper.InstallationMapperImpl.toEntity(InstallationMapperImpl.java:102)
When asking the conversion, the findById works correctly and retrieve the object and the nested one. It fails when the request is for 2nd level nested object, where the ObjectId is retrieved but cannot be converted and fails.
I'm answering myself because I found a solution suited for my problem.
I only needed the entity object with the id, so I wrote a converter:
public class ObjectIdToSubjectConverter implements Converter<ObjectId, Subject> {
#Override
public Subject convert(ObjectId source) {
return Subject.builder().id(source.toString()).build();
}
}
And register it as a bean:
#Configuration
public class MongoConfig {
#Bean
public MongoCustomConversions mongoCustomConversions() {
return new MongoCustomConversions(Collections.singletonList(new ObjectIdToSubjectConverter());
}
}

How to fix typing in hibernate "findBy" for enums?

I have an entity like so
public class SomeClass {
#NonNull
#NotNull
#Column(nullable = false)
#Convert(converter = SomeEnumConverter.class)
private SomeEnum fieldName;
}
I want to be able to find row in DB where the name of the enum matches to the string/enum which I pass. This table has only 2 columns. UUID which is PK and fieldName which is a varchar. I tried the following repository methods.
public interface SomeClassRepository extends AnotherRepository<SomeClass, UUID> {
Optional<SomeClass> findByFieldName(SomeEnum param);
}
public interface SomeClassRepository extends AnotherRepository<SomeClass, UUID> {
Optional<SomeClass> findByFieldName(String param);
}
My problem is if I try to find by passing a String (2nd case) it complains that my passed value is not the expected type(SomeEnum).
On the other hand if I pass the enum directly, It tries to look for rows with PK(UUID) = enum which I passed instead of searching on the other column(fieldName varchar). How do I get past this ?
public class SomeClass {
#Column(nullable = false)
#Enumerated(EnumType.STRING)
private SomeEnum fieldName;
}
public interface SomeClassRepository extends AnotherRepository<SomeClass, UUID> {
Optional<SomeClass> findByFieldName(SomeEnum param);
}
Please try this. This should work

How to solve Spring Boot findBy method with underscore variable

When I run the below project, I receive the following error. How can I fix it?
Caused by: java.lang.IllegalArgumentException: Failed to create query for method public abstract com.example.pharmanic.model.Rdhs_Hospital_Current_Stock com.example.pharmanic.repositories.Rdhs_Hospital_Current_StockRepository.findBysr_no(java.lang.String)! No property sr found for type Rdhs_Hospital_Current_Stock!
This is my Rdhs_Hospital_Current_Stock model class.
#Entity
#Data
#Table(name = "Rdhs_Hospital_Current_Stock")
public class Rdhs_Hospital_Current_Stock {
#Id
private Long batchId;
private int quantity;
private String expiredate;
#ManyToOne
private Hospital_By_Rdhs hospital_by_rdhs;
#ManyToOne
#JoinColumn(name = "sr_no", nullable = false, referencedColumnName = "sr_no")
private Medicine medicine;
}
sr_no is the foreign key of the Medicine table.
This is my Medicine entity:
#Data
#Entity
public class Medicine {
private #Id String sr_no;
private String name;
private String side_effect;
private String description;
public Medicine() {
}
public Medicine(String sr_no, String name, String side_effect, String description) {
this.sr_no = sr_no;
this.name = name;
this.side_effect = side_effect;
this.description = description;
}
}
When I use sr_no with my findBy() function:
#GetMapping("/rhstock/{id}")
ResponseEntity<?> getMedicine(#PathVariable String id){
Optional<Rdhs_Hospital_Current_Stock> rdhs_hospital_current_stock = Optional.ofNullable(rdhs_hospital_current_stockRepository.findBysr_no(id));
return rdhs_hospital_current_stock.map(response->ResponseEntity.ok().body(response)).orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
This is my repository:
public interface Rdhs_Hospital_Current_StockRepository extends JpaRepository<Rdhs_Hospital_Current_Stock,Long> {
Rdhs_Hospital_Current_Stock findBysr_no(String id);
}
Inspired from: Spring-Data-Jpa Repository - Underscore on Entity Column Name
The underscore _ is a reserved character in Spring Data query derivation (see the reference docs for details) to potentially allow manual property path description.
Stick to the Java naming conventions of using camel-case for member variable names and everything will work as expected.
Change sr_no to srNo.
Update repository function
Rdhs_Hospital_Current_Stock findBymedicine_srNo(String id);
I solve this error. I change in Reposity Interface & Controller class like as below
Repository Interface -:
#Query(value="select * from Rdhs_Hospital_Current_Stock h where h.sr_no = :sr_no",nativeQuery=true)
List<Rdhs_Hospital_Current_Stock> findBySr_no(#Param("sr_no")String sr_no);
Controller class -:
#RequestMapping(value = "/rhstocksr/{sr_no}", method = RequestMethod.GET)
List<Rdhs_Hospital_Current_Stock> getBatchByMedicine(#PathVariable("sr_no") String sr_no) {
return rdhs_hospital_current_stockRepository.findBySr_no(sr_no);
}
To keep using a derived query you may change sr_no to srNo.
You could solve this by starting using a native query, but my advice is to use derived querys everytime as it is possible to use it.

How to search nested property in Hibernate Criteria

My entity User has a nested property (in Oracle, it maps to a string field format as JSON) like the following snippet:
#Entity(name = "users")
public class User extends Auditable implements Serializable {
private Long id;
private String username;
private String password;
#Convert(converter = UserInformationConverter.class)
private UserInfomation additionalInformation;
}
public class UserInfomation {
private String email;
private String phoneNumber;
}
And then, I would like to search by the "email" property in the "additionalInformation" field in Criteria query. I tried:
predicate = cb.and(predicate, cb.like(root.get("additionalInformation").get("email"), cb.parameter(String.class, "email")));
But I got the error:
"Illegal attempt to dereference path source [null.additionalInformation] of basic type; nested exception is java.lang.IllegalStateException: Illegal attempt to dereference path source [null.additionalInformation] of basic type"
Please suggest me some solutions.
You can use the criteriaBuilder like:
cb.like(cb.lower(root.get("additionalInformation").get("email"));

Resources