JPAQuery with Spring Pageable - java

I'd like to use org.springframework.data.domain.Pageable with com.querydsl.jpa.impl.JPAQueryis there a way or is there a solid workaround how to make Pageable work with JPAQuery?

So I found nice why to make them work together posting full example:
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.PathBuilder;
import com.querydsl.jpa.impl.JPAQuery;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import javax.persistence.EntityManager;
public class Example {
public void example(Pageable pageable, EntityManager em){
QCustomer qCustomer = QCustomer.customer;
JPAQuery<?> query = new JPAQuery<>(em);
query.from(qCustomer);
BooleanBuilder builder = new BooleanBuilder();
builder.and(qCustomer.email.likeIgnoreCase("c#m.c"));
JPAQuery<?> where = query.where(builder);
// This for loop is making it work with Pagable
query.offset(pageable.getOffset());
query.limit(pageable.getPageSize());
PathBuilder<Customer> entityPath = new PathBuilder<>(Customer.class, "customer");
for (Sort.Order order : pageable.getSort()) {
PathBuilder<Object> path = entityPath.get(order.getProperty());
query.orderBy(new OrderSpecifier(Order.valueOf(order.getDirection().name()), path));
}
List<Customer> resultList = query.createQuery().getResultList();
}
}

Related

Hazelcast Json object querying

I'M storing these JSON Objects the hazelcast
IMap<String, HazelcastJsonValue> hazelcast = instance.getMap("get");
JSON thta I'm storing
{"id":"01","name":"abc","age":33}
{"id":"02","name":" data","age":37}
{"id":"03","name":"abc","age":39}
if i just want to select only age field with above 35
output:-
[37,39]
How to do this using projetions?
this works for me:
import com.hazelcast.core.*;
import com.hazelcast.projection.Projections;
import com.hazelcast.query.Predicates;
import org.junit.Test;
import java.util.Collection;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.Assert.assertThat;
[...]
#Test
public void testJsonProjection() {
HazelcastInstance hz = Hazelcast.newHazelcastInstance();
IMap<Integer, HazelcastJsonValue> map = instance.getMap("myMap");
map.set(0, new HazelcastJsonValue("{\"id\":\"01\",\"name\":\"abc\",\"age\":33}"));
map.set(1, new HazelcastJsonValue("{\"id\":\"02\",\"name\":\" data\",\"age\":37} "));
map.set(2, new HazelcastJsonValue("{\"id\":\"03\",\"name\":\"abc\",\"age\":39}"));
Collection<Long> projection = map.project(
Projections.singleAttribute("age"),
Predicates.greaterEqual("age", 35)
);
assertThat(projection, containsInAnyOrder(37L, 39L));
}

Request method 'GET' not supported] error for method using #DeleteMapping

I'm getting a error like:
Request method 'GET' not supported for a method (deleteProductById)
using the #DeleteMapping annotation whenever I visit the URL mapped to said method (http://localhost:8083/deleteproductbyid/1). The app works when I change the annotation for the method to #GetMapping but that causes other issues.
Here's the relevant code:
package com.democrudexample.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.democrudexample.model.Product;
import com.democrudexample.services.CrudService;
#RestController
#RequestMapping("/")
public class CrudRestController {
#Autowired
private CrudService service;
#GetMapping("/getproductlist")
#CrossOrigin(origins = "http://localhost:4200")
public List<Product> fetchProductList() {
List<Product> products = new ArrayList<Product>();
//logic to fetch list from database
products = service.fetchProductList();
return products;
}
#PostMapping("/addproduct")
#CrossOrigin(origins = "http://localhost:4200")
public Product saveProduct(#RequestBody Product product) {
return service.saveProductToDB(product);
}
#GetMapping("/getproductbyid/{id}")
#CrossOrigin(origins = "http://localhost:4200")
public Product fetchProductById(#PathVariable int id) {
return service.fetchProductById(id).get();
}
#DeleteMapping(value = "/deleteproductbyid/{id}")
#CrossOrigin(origins = "http://localhost:4200")
public String deleteProductById(#PathVariable int id) {
return service.deleteProductById(id);
}
}
package com.democrudexample.services;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.democrudexample.model.Product;
import com.democrudexample.repository.CrudRepo;
#Service
public class CrudService {
#Autowired
private CrudRepo repo;
public List<Product> fetchProductList(){
return repo.findAll();
}
public Product saveProductToDB(Product product) {
return repo.save(product);
}
public Optional<Product> fetchProductById(int id) {
return repo.findById(id);
}
public String deleteProductById(int id) {
String result;
try {
repo.deleteById(id);
result = "Product sucessfully deleted";
System.out.println(result);
}catch(Exception e) {
result = "Product id is not valid";
System.out.println(result);
}
return result;
}
}
EDIT: I commented out the result and everything related to it in the deleteProductById method and it seems to be working just fine now. After having looked at the console, the error seems to have been some issues with parsing the text.
By annotating the method as #DeleteMapping, you are making this a HTTP DELETE operation. Refer this documentation for more details about different HTTP requests.
However, when you access an URL in browser, browser always sends a GET request, whereas your Resource is expecting a DELETE request. Hence you are getting the error.
You can use tools like Postman or you can write a small code in Javascript to send a DELETE request to the server.

AssertionError: No value at JSON path, but value exists in valid JSON response

I saw many of solutions provided here, on the forum, and also a guide for the problem (provided here), but none of them helped me...
I tried to keep my code cleare as much as I can, so I decided to create many of test classes including test items, for example:
#Getter
#Setter
public class SalesTaskTestItem {
public static SalesTask buildTestItem(){
List<ContactPerson> contactPersonTestItemList = new ArrayList<>();
contactPersonTestItemList.add(ContactPersonTestItem.buildTestItem());
List<SalesMan> supportingSalesTeamList = new ArrayList<>();
List<Product> discussedProductsTestList = new ArrayList<>();
discussedProductsTestList.add(ProductTestItem.buildTestItem());
List<SalesTaskProgress> progressTestList = new ArrayList<>();
progressTestList.add(SalesTaskProgressTestItem.buildTestItemNo1());
progressTestList.add(SalesTaskProgressTestItem.buildTestItemNo2());
progressTestList.add(SalesTaskProgressTestItem.buildTestItemNo3());
List<Offer> alreadySentOffersTestList = new ArrayList<>();
alreadySentOffersTestList.add(OfferTestItem.buildTestItem());
List<AssignedTaskDocument> assignedTaskDocumentsTestList = new ArrayList<>();
assignedTaskDocumentsTestList.add(AssignedTaskDocumentTestItem.buildTestItem());
List<InternalProcedureDocument> internalProceduresDocumentsTestList = new ArrayList<>();
internalProceduresDocumentsTestList.add(InternalProcedureDocumentTestItem.buildTestItem());
SalesTask testItem = new SalesTask();
testItem.setId(1L);
testItem.setVersion(1);
testItem.setTaskEstablishedDate(DateFormatter.fromStringToDate("10-12-2020T09:12:45"));
testItem.setLastProgressDate(DateFormatter.fromStringToDate("10-12-2020T09:30:56"));
testItem.setCompany(CompanyTestItem.buildTestItem());
testItem.setContactPersonsList(contactPersonTestItemList);
testItem.setMainSalesMan(SalesManTestItem.buildTestItemNo1());
testItem.setSupportingSalesTeam(supportingSalesTeamList);
testItem.setDiscussedProducts(discussedProductsTestList);
testItem.setProgressList(progressTestList);
testItem.setCurrentTaskValue(BigDecimal.valueOf(250000));
testItem.setChanceOfPositiveFinishingTask(0.45);
testItem.setEstimatedDateOfFinishingTask(DateFormatter.fromStringToDate("30-12-2020T13:00:00"));
testItem.setAlreadySentOffersList(alreadySentOffersTestList);
testItem.setAssignedTaskDocumentsList(assignedTaskDocumentsTestList);
testItem.setInternalProceduresDocumentsList(internalProceduresDocumentsTestList);
return testItem;
}
}
My test case is:
package com.jmdev.storycrm.controllers;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.jmdev.storycrm.domain.salesTask.SalesTask;
import com.jmdev.storycrm.services.SalesTaskService;
import com.jmdev.storycrm.testDomainItems.salesTask.SalesTaskTestItem;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
#ExtendWith(SpringExtension.class)
#WebMvcTest
public class SalesTaskControllerTest {
#Autowired
MockMvc mockMvc;
#MockBean
private SalesTaskService salesTaskService;
#Test
public void createNewSalesTask(){
SalesTask newSalesTask = new SalesTask();
newSalesTask = SalesTaskTestItem.buildTestItem();
when(salesTaskService.save(any(SalesTask.class))).thenReturn(newSalesTask);
ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());
try {
String newSalesTaskJSON = objectMapper.writeValueAsString(newSalesTask);
ResultActions resultActions = mockMvc.perform(
post("/salesTask")
.contentType(MediaType.APPLICATION_JSON)
.content(newSalesTaskJSON)
);
resultActions.andExpect(status().isCreated())
.andDo(print())
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$.id").value(1L))
.andExpect(jsonPath("$.version").value(1))
.andExpect(jsonPath("$.taskEstablishedDate").value(SalesTaskTestItem.buildTestItem().getTaskEstablishedDate().toString()))
.andExpect(jsonPath("$.lastProgressDate").value(SalesTaskTestItem.buildTestItem().getLastProgressDate().toString()))
.andExpect(jsonPath("$.company").value(SalesTaskTestItem.buildTestItem().getCompany()))
.andExpect(jsonPath("$.contactPersonsList").value(SalesTaskTestItem.buildTestItem().getContactPersonsList()))
.andExpect(jsonPath("$.mainSalesMan").value(SalesTaskTestItem.buildTestItem().getMainSalesMan()))
.andExpect(jsonPath("$.supportingSalesTeam").value(SalesTaskTestItem.buildTestItem().getSupportingSalesTeam()))
.andExpect(jsonPath("$.discussedProducts").value(SalesTaskTestItem.buildTestItem().getDiscussedProducts()))
.andExpect(jsonPath("$.progressList").value(SalesTaskTestItem.buildTestItem().getProgressList()))
.andExpect(jsonPath("$.currentTaskValue").value(SalesTaskTestItem.buildTestItem().getCurrentTaskValue()))
.andExpect(jsonPath("$.chanceOfPositiveFinishingTask").value(SalesTaskTestItem.buildTestItem().getChanceOfPositiveFinishingTask()))
.andExpect(jsonPath("$.estimatedDateOfFinishingTask").value(SalesTaskTestItem.buildTestItem().getEstimatedDateOfFinishingTask()))
.andExpect(jsonPath("$.alreadySentOffersList").value(SalesTaskTestItem.buildTestItem().getAlreadySentOffersList()))
.andExpect(jsonPath("$.assignedTaskDocumentsList").value(SalesTaskTestItem.buildTestItem().getAssignedTaskDocumentsList()))
.andExpect(jsonPath("$.internalProceduresDocumentsList").value(SalesTaskTestItem.buildTestItem().getInternalProceduresDocumentsList()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
I see in stack trace my MockHttpServletResponse, where I can find "taskEstablishedDate":"2020-12-10T09:12:45.000+00:00". Also, If I copy whole body of this response and past it into https://jsonformatter.curiousconcept.com/, validation is passed with no problems.
MockHttpServletResponse:
Status = 201
Error message = null
Headers = [Content-Type:"application/json"]
Content type = application/json
Body = {"id":1,"version":1,"taskEstablishedDate":"2020-12-10T09:12:45.000+00:00","lastProgressDate":"2020-12-10T09:30:56.000+00:00", (...) }
Forwarded URL = null
Redirected URL = null
Cookies = []
But I get java.lang.AssertionError: No value at JSON path "$.taskEstablishedDate".
I really don't know what is wrong. Could anybody help?
EDIT: I implemented SSK suggestions and dates and time are passing now. For test next of JSON values, provided as my app's objects, I implemented GSON into override toString() method:
package com.jmdev.storycrm.domain.company;
import com.jmdev.storycrm.utils.JSONFormatter;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.Id;
#Entity
#Getter
#Setter
public class Company {
#Id
private Long id;
private String name;
private Long nipNumber;
private Address address;
#Override
public String toString() {
return JSONFormatter.useGSON(this);
}
}
Used toString() formatter:
package com.jmdev.storycrm.utils;
public class JSONFormatter {
public static String useGSON(Object object){
return new com.google.gson.Gson().toJson(object);
}
}
But I'm getting java.lang.AssertionError for both values which are completely the same...
java.lang.AssertionError: JSON path "$.company" (...)
Expected :{"id":1,"name":"TestCompanyName","nipNumber":345353534354335,"address":{"id":1,"voivodeship":"Region name","postalCode":"99-000","city":"My City name","street":"Main Street name","fullBiuldingNumber":"100","flatNumber":1}}
Actual :{"id":1,"name":"TestCompanyName","nipNumber":345353534354335,"address":{"id":1,"voivodeship":"Region name","postalCode":"99-000","city":"My City name","street":"Main Street name","fullBiuldingNumber":"100","flatNumber":1}}
You need to register your JavaTimeModule with ObjectMapper.
You can register JavaTimeModule as shown below.
ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());
Then use the same objectMapper to create the json string
String newSalesTaskJSON = objectMapper.writeValueAsString(newSalesTask);
JavaTimeModule is from com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
Also, you need to add .toString() to your date values in .andExpect() as shown below
.andExpect(jsonPath("$.taskEstablishedDate").value(SalesTaskTestItem.buildTestItem().getTaskEstablishedDate().toString()))
.andExpect(jsonPath("$.lastProgressDate").value(SalesTaskTestItem.buildTestItem().getLastProgressDate().toString()))
.andExpect(jsonPath("$.estimatedDateOfFinishingTask").value(SalesTaskTestItem.buildTestItem().getEstimatedDateOfFinishingTask().toString()))

Bitbucket Api with ssh access key as header to get total number of pull requests in java

I want to make a rest call to bitbucket api with ssh private key as header.For example the url is (http://bitbucket.com/rest/api/1.0/repos/testProject/pull-requests?state=OPEN).
Is there a way call this url with spring rest template and how to pass ssl access key as header.
Instead of using SSH keys use Personal Access Tokens:
https://confluence.atlassian.com/bitbucketserver/personal-access-tokens-939515499.html
(Introduced in Bitbucket 5.5)
Then you could use code like this:
package com.company.bitbucket.tools.application;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.stream.Collectors;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;
import com.company.bitbucket.tools.HttpRequestInterceptor;
import com.company.bitbucket.tools.ProjectValue;
import com.company.bitbucket.tools.Projects;
import com.company.bitbucket.tools.UserValue;
import com.company.bitbucket.tools.Users;
#Controller
public class ProjectController {
public static String BITBUCKET_URL = "https://bitbucket.company.com/rest/api/latest/";
public static String PROJECTS = "projects";
public static String PERMISSIONS = "permissions/users?permission=PROJECT_ADMIN";
public static String PAT = "<put your generated token in here>";
#RequestMapping(value={"/projects"}, method = RequestMethod.GET)
public ModelAndView listProjects(){
HashMap<String, String> list = getAdmins();
ModelAndView model = new ModelAndView("projects");
model.addObject("adminMap", list);
return model;
}
private HashMap<String, String> getAdmins(){
HashMap<String, String> projectMap = new HashMap<>();
RestTemplate restTemplate = new RestTemplate();
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>();
interceptors.add(new HttpRequestInterceptor("Authorization", "Bearer ".concat(PAT)));
restTemplate.setInterceptors(interceptors);
Projects projects = restTemplate.getForObject(BITBUCKET_URL.concat("projects?limit=100"), Projects.class);
for(ProjectValue projectValue: projects.getValues()) {
String projectUrl = String.format("%s/%s/%s/%s", BITBUCKET_URL, PROJECTS, projectValue.getKey(), PERMISSIONS);
Users users = restTemplate.getForObject(projectUrl, Users.class);
List<String> names = new ArrayList<>();
for (UserValue value: users.getValues()) {
names.add(value.getUser().getDisplayName());
}
String commaSeparatedNames = String.join(", ", names);
projectMap.put(projectValue.getName(), commaSeparatedNames);
}
return projectMap;
}
}
This code gets a list of project admins using the rest api, but you could change to make whatever rest request you wish.

Testing Java code and previewing the SQL statement

The following is a Java (Hibernate) Method. How can I write a test for it? I want the test method to return a SQL statement.The code reference a lot of other classes and packages which already exist. Ignore these and just show me how to integrate them in my test program.
#Override
public AppTacticalSubUnit returnByCode(String code) throws MyOwnDAOException {
Session session = getSession();
UnitOfWork unitOfWork = new UnitOfWork();
try {
unitOfWork.beginTransaction(session);
Criteria criteria = session.createCriteria(AppTacticalSubUnit.class);
criteriaAppTacticalSubUnit.add(Restrictions.eq("code", code));
criteriaAppTacticalSubUnit.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
setJoinFetches(criteria);
AppTacticalSubUnit ret = (AppTacticalUnit) criteria.uniqueResult();
unitOfWork.commit();
return ret;
} catch (HibernateException e) {
unitOfWork.rollback();
throw new ObelixxDAOException(e.getMessage(), e);
}
}
private void setJoinFetches(Criteria criteria) {
criteria.setFetchMode("appTacticalUnit.spaceOpsAreaServiceType", FetchMode.JOIN);
criteria.setFetchMode("appTacticalSubUnit.spaceOpsAreaServiceType.assExternalServiceType", FetchMode.JOIN);
criteria.setFetchMode("appTacticalSubUnit.spaceOpsAreaServiceType.assExternalServiceType.lookupServiceType", FetchMode.JOIN);
criteria.setFetchMode("appTacticalSubUnit.spaceOpsAreaServiceType.assExternalServiceType.lookupExternalServiceType", FetchMode.JOIN);
criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
criteria.addOrder(Order.asc("name"));
I have started something like this:
package na.co.sab.vitalix.db.dao;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.hsqldb.Session;
import na.co.sab.datashare.util.UnitOfWork;
import na.co.sab.vitalix.db.exception.MyOwnDAOException;
import na.co.sab.vitalix.db.util.HibernateOltpSessionUtil;
public class AppTacticalSubUnitTest {
//protected static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AppOTacticalSubUnitTest.class);
static protected HibernateOltpSessionUtil dataShareInstance;
public static void initializeVitalixOnHsql() throws Exception {
initializeVitalixOnHsql(true);
Have a look at this article http://java.dzone.com/articles/how-get-jpqlsql-string seems like it describes what you want.
The idea is to use org.hibernate.Query#getQueryString() method.

Categories