How Execute Stored Procedure using JPA annotation #NamedStoredProcedureQuery - java

How convert this procedure execution using #NamedStoredProcedureQuery?
I have this SQL, It's OK!
SQL (it's Works OK):
USE [INTEGRADOR]
GO
DECLARE #return_value int
EXEC #return_value = [dbo].[SP_VW_PEDIDOSDECOMPRA_SGM]
#CODIGO = 71648
SELECT 'Return Value' = #return_value
GO
In Java i Try this, but not working. idUsuarioAutenticado is #CODIGO = 71648
JAVA (Error when compile) :
#NamedStoredProcedureQuery(
name = "listarComprasMicrosigaProc",
procedureName = "INTEGRADOR.DBO.SP_VW_PEDIDOSDECOMPRA_SGM",
resultClasses = AcompanhamentoCompraPortalEntity.class,
parameters = {
#StoredProcedureParameter(mode = ParameterMode.IN, type = Long.class)
}
)
public List<AcompanhamentoCompraPortalEntity> listarComprasMicrosigaProc(#Param("idUsuarioAutenticado") Long idUsuarioAutenticado);
Not compile.
I received this errors:
The annotation #NamedStoredProcedureQuery is disallowed for this location
My imports (Java) :
import java.util.List;
import java.util.Set;
import javax.persistence.NamedStoredProcedureQuery;
import javax.persistence.StoredProcedureParameter;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

Instead of at field/attribute level, you have to add the #NamedStoredProcedureQuery annotation and its details at class level:
#Entity
#NamedStoredProcedureQuery(
// further specifications ...
)
public class MyEntity {
// fields, getter/setter methods, etc.
}
With that corrected, the error (message)
The annotation #NamedStoredProcedureQuery is disallowed for this location
should disappear.
Hope it helps.

Related

Spring — Passing List<String> of values in Payload POST API to Springframework.data.jpa.repository.Query "IN"

Lets assume we have one table/View with below columns
columns : ID , Status
I am writing one search API to get Data from backend
I am using org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
.....
#Repository
#Transactional
public interface UIDashboard extends JpaRepository<UIDashboardView, String> {
....
#Query(value = "SELECT results from SearchView results where "
+ "(:status is null or results.STATUS = :status) and"
+ "(coalesce(:ids) is null or results.ID in :ids)"
...
My DTO
import java.util.List;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import java.util.Optional;
import lombok.Data;
#Data
#JsonInclude(Include.NON_NULL)
public class SearchInputDTO {
#JsonProperty(value="status",required = false)
private String status;
#JsonProperty(value="ids",required = false)
//private Optional<List<String>> ids;
//ArrayList<String> ids;
private List<String> ids;
REST API
import org.springframework.web.bind.annotation.PostMapping;
...
#PostMapping("/searchTest")
public ResponseEntity<List<ResultsDTO>> search_test(
#RequestBody #NotNull #Valid SearchInputDTO payload, HttpServletRequest request)
throws IOException {
}
{
"status" : "COMPLETED",
"ids" : [null,null]
}
Issue with the approach is to invoke POST REST API i need to send two null values [null,null] in payload i,e without id's property i am unable to execute POST API , so either i need to send null values or set in DTO.
I also tried to make Optional in DTO or
Used coalesce -> (coalesce(:ids) is null or results.ID in :ids)
i dont want to explicitly send null values in Payload , User can search with any parameter for example only with one property :status:
{
"status" : "INPROCESS"
}
Above payload not working as i am not sending "ids"
Then i tried set nulls in setter as workaround
#JsonProperty(value="ids",required = false)
private List<String> ids = new ArrayList<>(Arrays.asList(null, null));
#JsonSetter("ids")
public void setIds(List<String> li){
if (li != null) {
if (li.size() < 2){
li.add(null);
li.add(null);
this.ids = li;
}
else{
this.ids = li;
}
}
}
I dont like this work around , is there any better solution or changes required to JPQL IN parameter or SearchInputDTO .
I also followed blog Spring Data repository with empty IN clause
Thanks,
Showkath.

MongoShell query to MongoRepository

db.getCollection('parentCollection').find({"mapObject.someField" : {$exists: true}})
i want this to convert into method like below
.
#Query("{mapObject.someField :{$exists : true}}")
List<Parent> findByMapKey(String id);
Here i am getting null pointer exception while running application
#Query("{mapObject.someField :{$exists : true}}")
here someField needs to be dynamic not fixed so i want my id to be passed in place of someField
Same question exists here as well
How to get parent object based upon key from child map in MongoRepository JAVA SpringBoot
It's not possible to do with MongoRepository. Instead, use MongoTemplate.
As mentioned above by #Valijon it is not possible with #Query annotation. Still if anyone finds a way please share. Following is how i achieved it using MongoTemplate
package com.somepackage.services;
import org.springframework.stereotype.Service;
import java.util.List;
import com.yourpackagestructure.Parent;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
#Service
public class Service{
private MongoTemplate mongoTemplate;
public Service(MongoTemplate mongoTemplate){
this.mongoTemplate = mongoTemplate;
}
public List<Parent> getParentList(String mapKey){
Query query = new Query();
query.addCriteria(Criteria.where("someMap." + mapKey).exists(true));
List<Parent> parents = mongoTemplate.find(query,Parent.class);
}
}

How to execute Java calls to GraphQL in a Spring Boot + GraphQL Java Tools' context?

In a Spring Boot application, we're already having a fully functional GraphQL endpoint, serving .graphqls files via GraphQL Java Tools (we included the graphql-spring-boot-starter dependency) and handling the data resolution through our base Query class implementing GraphQLQueryResolver and subsequent GraphQLResolver's.
For a business need, we have to re-create standard REST API endpoints, so I wonder why not just making calls to GraphQL (instead of having to re-implement "by hand" the data resolution once again)?
And as it's in the same backend application, no need to make HTTP or servlet (ForwardRequest) calls, just call some API's in Java.
The thing is I don't know how to proceed.
I read this example, but it's with basic GraphQL Java (not Tools):
https://www.graphql-java.com/documentation/v9/execution/
I know this should possible because we are allowed to do this in tests:
https://github.com/graphql-java-kickstart/graphql-spring-boot/blob/master/example-graphql-tools/src/test/java/com/graphql/sample/boot/GraphQLToolsSampleApplicationTest.java
But how to do it in regular code? There is not such thing as a GraphQLTemplate.
I also tried to search through examples at:
https://github.com/graphql-java-kickstart/graphql-java-tools/tree/master/example
https://github.com/graphql-java-kickstart/graphql-spring-boot
but found nothing relevant to our need.
Found nothing more in Documentation:
https://www.graphql-java-kickstart.com/tools/
https://www.graphql-java-kickstart.com/spring-boot/
What did I miss? Ideally I'm looking to inject some GraphQLSomething like this:
#RestController
#RequestMapping(path = "api")
public class CompanyController {
#Autowired
private GraphQLSomething graphQLSomething;
#GetMapping("company/{id}")
public ResponseEntity<?> societe(#PathVariable #NotNull Integer id) {
GraphQLSomethingResult result = GraphQLSomething.query("company(id: $id) { id name andsoone }", "{ \"id\": 123456 }").execute(); // not really sure of the GraphQL syntax here, but it'll need some tests...
return result.getDataOrElse();
}
}
Finally found how to do the thing as I wanted:
import java.util.Map;
import java.util.Optional;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Positive;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.google.common.collect.ImmutableMap;
import graphql.ExecutionResult;
import graphql.servlet.core.GraphQLQueryInvoker;
import graphql.servlet.core.internal.GraphQLRequest;
import graphql.servlet.input.GraphQLInvocationInputFactory;
import graphql.servlet.input.GraphQLSingleInvocationInput;
import lombok.extern.slf4j.Slf4j;
#Slf4j
#Validated
#RestController
#RequestMapping(path = "api")
public class CompanyController {
#Autowired
private GraphQLInvocationInputFactory invocationInputFactory;
#Autowired
private GraphQLQueryInvoker queryInvoker;
#GetMapping("company/{id}")
public ResponseEntity<?> societe(#PathVariable #NotNull Integer id) {
String query = "query ($id: Int!) { company(id: $id) { id name andsoon } }";
/*
* ImmutableMap is a Guava class; you can build the map (e.g. a HashMap) on your
* own, or simply Map.to(..) in Java 9, or even #PathVariable Map<String,
* Object> variables as the method's parameter instead (but you'll miss the
* validation).
*/
Map<String, Object> variables = ImmutableMap.of("id", id);
GraphQLRequest request = new GraphQLRequest(query, variables, null);
GraphQLSingleInvocationInput invocationInput = invocationInputFactory.create(request);
ExecutionResult result = queryInvoker.query(invocationInput);
/*
* Of course result.getData() can be null here - see also result.isDataPresent()
* - but data/error handling's left to you
*/
Optional<Object> company = Optional.ofNullable(result.getData().get("company"));
return ResponseEntity.of(company);
}
}
FYI, to get the dependencies for the above code, you'll need this:
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-spring-boot-autoconfigure</artifactId>
<version>5.0.2</version>
</dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-servlet</artifactId>
<version>6.1.3</version>
</dependency>

“ConverterNotFoundException” in Spring boot JPA

I want to get the SearchOutput data object by calling a query(#Query method) with natural joins of 3 tables. but when the query runs it shows an error.
I have tried to fetch the data in my spring boot controller class. But its not working because of the error
package com.example.mysqlproj.model;
import lombok.*;
public class SearchOutput {
private String hotel_name;
private String room_type;
private int price;
}
package com.example.mysqlproj.dao;
import com.example.mysqlproj.model.Room_Type;
import com.example.mysqlproj.model.SearchOutput;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import java.util.Collection;
import java.util.Date;
import java.util.List;
public interface RoomTypeDao extends CrudRepository<Room_Type,Integer> {
#Query(value="select new SearchOutput(hotel_name , room_type,(price*(?4)*(?3)*(1.15))) from Room_type natural join Hotel natural join True_contract where (?1 >= start_date and ?2 <= end_date and ?3 <=available_rooms and ?4<= max_adults )", nativeQuery = true)
List<SearchOutput[]> checkHotelList(Date from, Date to, int rooms, int adults, int total_nights);
}
The Error:
No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [com.example.mysqlproj.model.SearchOutput]] with root cause
My target is to fetch a searchOutput object array when the query gets called.
Are there any solutions for this. Thanks in advance
The response type from the query is
List<Map<String, Object>> .
Please change the method return type to this.

Clashes between count() methods - CrudRepository - Spring

I prefer to warn you, my english is not perfect but I'll try to do my best.
I'm actually in an internship and my task is to create a webservice. Before this, I'm supposed to work with Maven and create repositories, models and others.
For now, I've got a problem with the repository of a simple Java class.
Here is my class :
package com.XXX;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.Id;
import java.sql.Timestamp;
#Entity
//Generate getters and setters
#Data
//Generate a constructor with to arguments
#NoArgsConstructor
public class Day_ {
#Id
private int day_id_Date;
private Timestamp day_Date;
public Day_(int day_id_Date, Timestamp day_Date) {
this.day_id_Date = day_id_Date;
this.day_Date = day_Date;
}
}
Pretty simple as I said.
Now here comes my repository :
package com.XXX;
import com.XXX.Day_;
import org.springframework.data.repository.CrudRepository;
public interface DayRepository extends CrudRepository<Day_, Long> {
}
I've actually took this from an example on internet. Works fine for him but not for me. I'm getting the following error :
Error:(6, 8) java: types org.springframework.data.repository.Repository<com.atos.test.account.tables.Day_,java.lang.Long> and org.springframework.data.repository.CrudRepository<com.atos.test.account.tables.Day_,java.lang.Long> are incompatible; both define count(), but with unrelated return types
Now I've tried to override the count() method by doing :
package com.XXX;
import com.XXX.Day_;
import org.springframework.data.repository.CrudRepository;
public interface DayRepository extends CrudRepository<Day_, Long> {
#Override
long count();
}
But I get the following error (which is almost the same) :
Error:(6, 8) java: types org.springframework.data.repository.CrudRepository<com.atos.test.account.tables.Day_,java.lang.Long> andorg.springframework.data.repository.Repository<com.atos.test.account.tables.Day_,java.lang.Long> are incompatible; both define count(), but with unrelated return types
Error:(9, 10) java: count() in com.atos.test.account.repository.DayRepository clashes with count() in org.springframework.data.repository.Repository return type long is not compatible with java.lang.Long
I've looked into the CrudRepository class but the methods count() is the same than the one I tried. I've also looked into the Repository class because CrudRepository extends it but there is no method count.
EDIT
So I think I've resolved the problem :
Instead of extending my interface to CrudRepositoryI extended it to Repository. The thing is that I don't know if I can use the same methods ther is in CrudRepository, can I ?
You need to return type "Long".
#Override
Long count();

Categories