How to pass the Timestamp in GetMapping - spring-boot

Im trying to fetch the data from DB which is updated from todays date to last 30days updated data(Timestamp)
Controller-class
#GetMapping("/getcodeByTs/createdTs")
public List<CodeSet> getCodeSetByCreatedTs(#RequestBody Timestamp createdTs){
return codesetService.getCodeSetByCreatedTs(createdTs);
}
Service-layer
public List<CodeSet> getCodeSetByCreatedTs(Timestamp createdTs){
return codeRepo.findCodeSetByCreatedTs(createdTs);
}
Repository
#Query(value="Select * from CODE_SET Where CREATED_TS = ? ",nativeQuery=true)
public List<CodeSet> findCodeSetByCreatedTs(Timestamp createdTs);
postman-output
Required request body is missing: public
java.util.List<com.example.first.entity.CodeSet>
com.example.first.controller.CodeSetController.getCodeSetByCreatedTs(java.sql.Timestamp)
How can i fetch the data from DB

Related

Java Date field not shown properly in postman

Any help or hint would be greatly appreciated it!!
I am using Spring Boot 2.56
The date and time show properly for field "transactionDate" field when debugging the code in intellij.
2023-01-15 23:35:05.0
enter image description here
Code:
public List < TransactionEntity > findByFromAccountIdOrToAccountId(Long accountId) {
AccountEntity account = accountRepository.findByAccountId(accountId);
if (account == null) {
throw new AccountException("account cannot be found in account table accountId:" + accountId);
}
List < TransactionEntity > list = transactionRepository.findByFromAccountOrToAccount(account, account);
return list;
}
TransactionEntity.java
private Timestamp transactionDate;
For the transactionDate field I used import java.sql.Timestamp;
In postman it is showing: "transactionDate": 1673843714000,
How can I show the proper date and time in postman result such as "2023-01-15 23:35:05.0".
"transactionDate": 1673843714000
This is how Timestamp looks like. If you want to show like you mention use LocalDateTime instead.
private LocalDateTime transactionDate;
Or convert
transactionDate.toLocalDateTime().toLocalDate()

How to iterate from the JPA query in spring boot based on the virtual table such as (the count of students for courses tutorials taken)

I need to retrieve each student with number of courses taken, for example :
count
student
5
John
8
Jenny
And I need the following JSON response from my rest end-point:
[
{
"name_student": John,
"count_course": 5,
},
{
"name_student": Jenny,
"count_course": 8,
},
]
I have made the query to fetch the required data inside the Repository:
#Query(value ="Select count(*), s.student_name from student s INNER JOIN courses c on c.student_id= s.student_id group by s.student_name", nativeQuery = true )
List<StudentDTO> getIncidentCountByOfficerKPI ()
My DTO:
#Data
#NoArgsConstructor
public class StudentDTO {
Integer count;
String StudentName;
}
Service:
public List<StudentDTO> getStudentCount() {
return p2StudentRepository.getIncidentCountByOfficerKPI ();
}
Controller:
#GetMapping("/Student-count")
public ResponseEntity<StudentDTO> getAllStudentCount() {
List<StudentDTO> selectedCount = p2StudentService.getStudentCount();
List<StudentDTO> result = new ArrayList<>();
selectedCount.forEach(i -> {
StudentDTOitem = new StudentDTO();
item.setUserName(i.getStudentName());
item.setCount(i.getCount());
result.add(item);
});
return ResponseEntity.ok(result);
}
when I test with postman, it returns to nothing like below
[]
How can I fix that?
The return type of your rest end-point is incorrect, it should be ResponseEntity<List<StudentDTO>> (since you need to place multiple StudentDTO in the response).
And to provide ResponseEntity with a response body, you can use body() method of the ResponseEntity.BodyBuilder (that's a builder-object produced by the static method ResponseEntity.ok()), or it can be done by using of the parameterized constructors of the ResponseEntity.
And since you're actually not transforming the data returned by getStudentCount() you can attach this list as the response body directly.
#GetMapping("/Student-count")
public ResponseEntity<List<StudentDTO>> getAllStudentCount() { // <- change the return type
List<StudentDTO> selectedCount = p2StudentService.getStudentCount();
return ResponseEntity.ok()
.body(selectedCount); // <- add the response body
}

findByDate returning documents from previous day

I'm trying to fetch a list of objects by date, but the resulted list is always of the day before.
#GetMapping("date")
ResponseEntity findByDate(#RequestParam #DateTimeFormat(pattern = "yyyy-MM-dd") Date date) {
log.info("date is: "+date);
log.info("Delfaul time zone is: "+ TimeZone.getDefault());
return ResponseEntity.ok(consumptionService.findByDate(date));
}
the controller calls the service, which calls HourlyConsumptionRepo:
public interface HourlyConsumptionRepo extends MongoRepository<HourlyConsumption, ObjectId> {
List<HourlyConsumption> findByDate(Date date);
}
Postman results
Postman results
I think it might be an issue of timezones, but I can't figure out how to fix it.
MongoDB uses UTC times by default. See here: https://www.mongodb.com/docs/v3.2/tutorial/model-time-data/. So those results are "valid", I'm assuming you are UTC+2.

InvalidPathException while sorting with org.springframework.data.domain.Pageable

I am trying to sort my table's content on the backend side, so I am sending org.springframework.data.domain.Pageable object to controller. It arrives correctly, but at the repository I am getting org.hibernate.hql.internal.ast.InvalidPathException. Somehow the field name I would use for sorting gets an org. package name infront of the filed name.
The Pageable object logged in the controller:
Page request [number: 0, size 10, sort: referenzNumber: DESC]
Exception in repository:
Invalid path: 'org.referenzNumber'","logger_name":"org.hibernate.hql.internal.ast.ErrorTracker","thread_name":"http-nio-8080-exec-2","level":"ERROR","level_value":40000,"stack_trace":"org.hibernate.hql.internal.ast.InvalidPathException: Invalid path: 'org.referenzNumber'\n\tat org.hibernate.hql.internal.ast.util.LiteralProcessor.lookupConstant(LiteralProcessor.java:111)
My controller endpoint:
#GetMapping(value = "/get-orders", params = { "page", "size" }, produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<PagedModel<KryptoOrder>> getOrders(
#ApiParam(name = "searchrequest", required = true) #Validated final OrderSearchRequest orderSearchRequest,
#PageableDefault(size = 500) final Pageable pageable, final BindingResult bindingResult,
final PagedResourcesAssembler<OrderVo> pagedResourcesAssembler) {
if (bindingResult.hasErrors()) {
return ResponseEntity.badRequest().build();
}
PagedModel<Order> orderPage = PagedModel.empty();
try {
var orderVoPage = orderPort.processOrderSearch(resourceMapper.toOrderSearchRequestVo(orderSearchRequest), pageable);
orderPage = pagedResourcesAssembler.toModel(orderVoPage, orderAssembler);
} catch (MissingRequiredField m) {
log.warn(RESPONSE_MISSING_REQUIRED_FIELD, m);
return ResponseEntity.badRequest().build();
}
return ResponseEntity.ok(orderPage);
}
the repository:
#Repository
public interface OrderRepository extends JpaRepository<Order, UUID> {
static final String SEARCH_ORDER = "SELECT o" //
+ " FROM Order o " //
+ " WHERE (cast(:partnerernumber as org.hibernate.type.IntegerType) is null or o.tradeBasis.account.retailpartner.partnerbank.partnerernumber = :partnerernumber)"
+ " and (cast(:accountnumber as org.hibernate.type.BigDecimalType) is null or o.tradeBasis.account.accountnumber = :accountnumber)"
+ " and (cast(:orderReference as org.hibernate.type.LongType) is null or o.tradeBasis.referenceNumber = :orderReference)"
+ " and (cast(:orderReferenceExtern as org.hibernate.type.StringType) is null or o.tradeBasis.kundenreferenceExternesFrontend = :orderReferenceExtern)"
+ " and (cast(:dateFrom as org.hibernate.type.DateType) is null or o.tradeBasis.timestamp > :dateFrom) "
+ " and (cast(:dateTo as org.hibernate.type.DateType) is null or o.tradeBasis.timestamp < :dateTo) ";
#Query(SEARCH_ORDER)
Page<Order> searchOrder(#Param("partnerernumber") Integer partnerernumber,
#Param("accountnumber") BigDecimal accountnumber, #Param("orderReference") Long orderReference,
#Param("orderReferenceExtern") String orderReferenceExtern, #Param("dateFrom") LocalDateTime dateFrom,
#Param("dateTo") LocalDateTime dateTo, Pageable pageable);
}
Update:
I removed the parameters from the sql query, and put them back one by one to see where it goes sideways. It seems as soon as the dates are involved the wierd "org." appears too.
Update 2:
If I change cast(:dateTo as org.hibernate.type.DateType) to cast(:dateFrom as date) then it appends the filed name with date. instead of org..
Thanks in advance for the help
My guess is, Spring Data is confused by the query you are using and can't properly append the order by clause to it. I would recommend you to use a Specification instead for your various filters. That will not only improve the performance of your queries because the database can better optimize queries, but will also make use of the JPA Criteria API behind the scenes, which requires no work from Spring Data to apply an order by specification.
Since your entity Order is named as the order by clause of HQL/SQL, my guess is that Spring Data tries to do something stupid with the string to determine the alias of the root entity.

Spring Mongodb query for Employee first and last name and dob using range criteria

I have some data on employees which stores typical information like first and last name and dob, etc... The business case I have been given requires me to pull a record for an employee based on a criteria of first name, last name and dob.
At first I thought this would be easy, but after doing a search in db, I found the dob records have differing timestamps (which doesn't make sense). Without getting into the internal company issues of addressing this, I need my query to look at a dob with a start of day and end of day range.
My sample code below demonstrates my latest effort to solve this issue but have not been able to match results with what i see in the db. This code is using Spring Mongodb Query and mongoDbTemplate for constructing the queries. I could really use some help in figuring this one out.
I have to set a date range to ensure I get the employee for that day but can't figure out how to construct the query correctly.
sample method:
#Slf4j
#Repository
public class EmployeeDao {
private static final int START_OF_DAY = 0;
private static final int END_OF_DAY = 1;
#Getter private MongoTemplate mongoTemplate;
#Autowired
public void setMongoTemplate(MongoTemplate mongoTemplate) {
DB db = mongoTemplate.getDb();
mongoTemplate = new MongoTemplate(db.getMongo(), "EmployeeDB");
this.mongoTemplate = mongoTemplate;
}
public List<Employee> findEmployeeByNameIdDobRange(String lName, String fName, Date dob){
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
String startFmt = df.format(convertTo(dob, START_OF_DAY));
String endFmt = df.format(convertTo(dob, END_OF_DAY));
Query q = new Query();
q.addCriteria(Criteria.where("employee.firstName").regex(fName, "i")
.and("employee.lastName").regex(lName, "i")
.andOperator(
Criteria.where("employee.dob").gte(startFmt).lte(endFmt)
)
);
return return getMongoTemplate().find(q, Employee.class);
}
private Date convertTo(Date dt, int startOrEnd){
Calendar cal = Calendar.getInstance();
cal.setTime(dt);
switch (startOrEnd) {
case END_OF_DAY:
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 999);
break;
case START_OF_DAY:
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 1);
cal.set(Calendar.SECOND, 1);
cal.set(Calendar.MILLISECOND, 1);
break;
default:
throw new IllegalArgumentException("starOrEnd paramter does not equal 0 for beggining or 1 for end of day");
}
log.info(cal.toString());
return cal.getTime();
}
I appreciate any suggestions that can be made. Thanks!

Resources