Type cast issue for [Ljava.lang.Object - spring

public List<Client> findClientByAssociateUser(String userId) {
logger.info("Enter find list of clients by this user");
org.hibernate.Query query = sessionFactory.getCurrentSession()
.createQuery("SELECT c.id, c.clientName, c.billingAddress,c.contactNumber"
+ " from Client c, User ud"
+ " WHERE ud.id = c.userId and ud.id = :id")
.setString("id", userId);
List<Client> result = (List<Client>) query.list();
logger.info("Exit find list of clients");
return result;
}
public ModelAndView userDetails(#PathVariable String id, HttpServletRequest request) {
ModelAndView mvc = new ModelAndView();
List<Client> clientList = userRepository.findClientByAssociateUser(id.toString());
mvc.addObject("clientList", clientList);
for (Client client : clientList) {
System.out.println("Client Name{" + client.getClientName());
}
mvc.setViewName(MANAGEUSER_PREFIX + "details");
return mvc;
}
I am getting:
Ljava.lang.Object; cannot be cast to Client

The return type in the query would be List<Object[] >.
Because your query says
SELECT c.id, c.clientName, c.billingAddress,c.c......
change
List<Client> result = (List<Client>) query.list();
and then process according to that
to
List<Object[]> result = (List<Object[]>) query.list();
or change the query to
SELECT c from Client c......

Related

How to Implement Spring Boot Paging and multiple filtering using Criteria Api

Today was my first time with criteria Api. i have create an application in Spring boot in order to make server side pagination with multiple key of an entity filtering.
So in my case i have created an entity called User and i started to implement code to paginate the data but with Criteria API.
After implementing the pagination without filtering and Criteria Api everything worked perfectly! every page return 8 results and it is well organized by current page, totalPages, etc ..
But later i have decided to start to implement Criteria API by searching my entity username and userRole. my goal is to make that paging i did in the last step mixed with filtering of keys.
In case that my keys are empty then paginate else paginate and filter.
So after implementing i have discouvered that filtering works perfectly but pagination do not work correctly anymore because i am receiving all the results in every page.
that problem happened only after implementing Criteria API which i just discovered today.
I am trying to reach my goal by keeping all i spoke about in one query and paginate correctly
Here what i have done with my UserCriteriaRepository
#Repository
public class UserCriteriaRepository {
private final EntityManager entityManager;
private final CriteriaBuilder criteriaBuilder;
public UserCriteriaRepository(EntityManager entityManager) {
this.entityManager = entityManager;
this.criteriaBuilder = entityManager.getCriteriaBuilder();
}
public ResponsePagingAndSorting<UserDTO> findAllWithFilters(int page, int size, String username, String userRole) {
CriteriaQuery<User> criteriaQuery = criteriaBuilder.createQuery(User.class);
Root<User> userRoot = criteriaQuery.from(User.class);
Predicate predicate = getPredicate(username,userRole, userRoot);
criteriaQuery.where(predicate);
TypedQuery<User> typedQuery = entityManager.createQuery(criteriaQuery);
typedQuery.setMaxResults(size * 10);
long usersCount = getUsersCount(predicate);
int totalPages = (int) ((usersCount / size) + 1);
List<User> userList = new ArrayList<>();
userList = typedQuery.getResultList();
List<UserDTO> userDTOList = UserMapper.toListDTO(userList);
return new ResponsePagingAndSorting<UserDTO>("Users List ",200,userDTOList,page,
usersCount, totalPages);
}
private Predicate getPredicate(String username, String userRole,
Root<User> userRoot) {
List<Predicate> predicates = new ArrayList<>();
if(Objects.nonNull(username)){
predicates.add(
criteriaBuilder.like(userRoot.get("username"),
"%" + username + "%")
);
}
if(Objects.nonNull(userRole)){
UserRoleType userRoleType = null;
switch (userRole){
case "MEMBER": userRoleType = UserRoleType.MEMBER;
break;
case "ADMIN": userRoleType = UserRoleType.ADMIN;
break;
case "SUPER_ADMIN": userRoleType = UserRoleType.SUPER_ADMIN;
break;
}
if (userRoleType != null) {
predicates.add(
criteriaBuilder.equal(userRoot.get("userRole"),
userRoleType)
);
}
}
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
}
private Pageable getPageable(int page, int size) {
return PageRequest.of(page,size);
}
private long getUsersCount(Predicate predicate) {
CriteriaQuery<Long> countQuery = criteriaBuilder.createQuery(Long.class);
Root<User> countRoot = countQuery.from(User.class);
countQuery.select(criteriaBuilder.count(countRoot)).where(predicate);
return entityManager.createQuery(countQuery).getSingleResult();
}
}
My Service:
//paging with Criteria Api
#Override
public ResponsePagingAndSorting<UserDTO> getAllUsers(int page, int size ,String username, String userRole) {
ResponsePagingAndSorting<UserDTO> response = userCriteriaRepository.findAllWithFilters(page,size, username, userRole);
return response;
}
My Controller
#GetMapping("/get/all")
#ResponseBody
public ResponsePagingAndSorting<UserDTO> getAllUsers(#RequestParam(defaultValue = "0") int page,
#RequestParam(defaultValue = "8") int size,#RequestParam(defaultValue = "") String username,
#RequestParam(defaultValue = "") String userRole) {
ResponsePagingAndSorting<UserDTO> response = userService.getAllUsers(page,size,username,userRole);
log.warn("Response controller is " + response);
return response;
}
My ResponsePagingAndSorting dto object:
#AllArgsConstructor
#NoArgsConstructor
#Data
public class ResponsePagingAndSorting<T> {
String message;
int status_code;
List<T> body = new ArrayList<>();
int currentPage;
long totalItems;
int totalPages;
}
In Database i have in total of 17 users, so in postman i see all the 17 everytime but if i search by username or userRole or both it works? why pagination works only when i user the filters?
Can not i paginate data without seraching by username or userRole?
what is wrong with my code ???
how to make pagination works correctly with the filtering enabled or disabled?
Why if
Postman screen capture:
unfortunately all results are displayed in page 0
Screen Capture pagination + username filter: works correctly
i hope that i will find a solution
Problem Solved by using JpaSpecification
here the Specification class:
#Component
public class UserSpecification {
public Specification<User> getUsers(String username, String userRole) {
return (root, query, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
if (username != null && !username.isEmpty()) {
predicates.add(criteriaBuilder.like(criteriaBuilder.lower(root.get("username")),
"%" + username.toLowerCase() + "%"));
}
if (userRole != null && !userRole.isEmpty()) {
UserRoleType userRoleType = null;
switch (userRole) {
case "MEMBER": userRoleType = UserRoleType.MEMBER;
break;
case "ADMIN": userRoleType = UserRoleType.ADMIN;
break;
case "SUPER_ADMIN": userRoleType = UserRoleType.SUPER_ADMIN;
break;
}
predicates.add(criteriaBuilder.equal(root.get("userRole"), userRoleType));
}
query.orderBy(criteriaBuilder.asc(root.get("username")));
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
};
}
}

Can I use `#Cacheable` in a Controller?

I want to cache my database access but I have no Repositories. This is how I'm doing (please don't ask why. This is not the point here):
#RequestMapping(value = "/database", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
public List<User> testDatabaseCache( #RequestParam("username") String userName ) {
Object[] params = new Object[] { userName };
String sql = "select * from public.users where user_name = ?";
List<User> users = jdbcTemplate.query(sql, params, new UserMapper() );
log.info("Database hit: " + userName);
return users;
}
So... since I have no repository to annotate as cacheable, what can I do?

Unable to update Data to DB : org.hibernate.hql.internal.QueryExecutionRequestException: Not supported for DML operations

i was trying to update database tables by using following Hibernate Query Language
#RequestMapping(value = "/update",method = RequestMethod.POST)
public #ResponseBody String update(#RequestParam(value = "score1",required = true) String score1,
#RequestParam(value = "score2",required = true) String score2,
#RequestParam(value = "score3",required = true) String score3,
#RequestParam(value = "score4",required = true) String score4,
#RequestParam(value = "id",required = true)String id,
Model model)
{
SessionFactory sessionFactory=new Configuration().configure("hibernate.cfg.xml")
.addAnnotatedClass(User.class)
.addAnnotatedClass(UserDetail.class)
.addAnnotatedClass(UserScores.class).buildSessionFactory();
Session session=sessionFactory.getCurrentSession();
try
{
System.out.println("ID is"+id);
session.beginTransaction();
session.createQuery("update UserScores u set " +
"u.score1=:score1," +
"u.score2=:score2," +
"u.score3=:score3," +
"u.score4=:score4 where u.ID=:id")
.setParameter("score1",score1)
.setParameter("score2",score2)
.setParameter("score3",score3)
.setParameter("score4",score4)
.setParameter("id",id);
session.getTransaction().commit();
session.close();
}
catch (Exception e)
{
System.out.println(e);
}
return score1+score2+score3+score4;
}
after executing this code, it doesnt give any error , but the data is not updated in the database
what is the problem in executing this code
Its working, i tried it in another way
#RequestMapping(value = "/update",method = RequestMethod.POST)
public #ResponseBody String update(#RequestParam(value = "score1",required = true) String score1,
#RequestParam(value = "score2",required = true) String score2,
#RequestParam(value = "score3",required = true) String score3,
#RequestParam(value = "score4",required = true) String score4,
#RequestParam(value = "id",required = true)String id,
Model model)
{
SessionFactory sessionFactory=new Configuration().configure("hibernate.cfg.xml")
.addAnnotatedClass(User.class)
.addAnnotatedClass(UserDetail.class)
.addAnnotatedClass(UserScores.class).buildSessionFactory();
Session session=sessionFactory.getCurrentSession();
try
{
session.beginTransaction();
System.out.println("ID is"+id);
UserScores userScores=session.get(UserScores.class,Integer.parseInt(id));
userScores.setScore1((Double.parseDouble(score1)));
userScores.setScore2((Double.parseDouble(score2)));
userScores.setScore3((Double.parseDouble(score3)));
userScores.setScore4((Double.parseDouble(score4)));
session.update(userScores);
session.getTransaction().commit();
session.close();
}
catch (Exception e)
{
System.out.println(e);
}
The query that you are creating needs to be executed using query.executeUpdate()
session.beginTransaction();
Query query = session.createQuery("update UserScores u set " +
"u.score1=:score1," +
"u.score2=:score2," +
"u.score3=:score3," +
"u.score4=:score4 where u.ID=:id");
query.setParameter("score1",score1)
query.setParameter("score2",score2)
query.setParameter("score3",score3)
query.setParameter("score4",score4)
query.setParameter("id",id);
query.executeUpdate();
session.getTransaction().commit();
session.close();
An alternative way is to make changes to the persistent entities. In this case the updates will be automatically propogated.

How to combine 2 responseEntity and return?

how can i combine 2 different responseEntity and return
public ResponseEntity<?> getObject(#PathVariable("shopId") String shopId,
#PathVariable("delearId") String delearId) {
Shop objectToSave = (shopId.equalsIgnoreCase("0")) ? (null) : shopService.findOne(shopId);
Delear objectName = (delearId.equalsIgnoreCase("0")) ? null : delearService.findOne(delearId);
ResponseEntity<?> responseEntity = new ResponseEntity<>(objectName && objectToSave , HttpStatus.OK);// i want to combine both delear and shop
if (objectName == null && objectToSave == null) {
responseEntity = new ResponseEntity<>(objectName,objectToSave , HttpStatus.NOT_FOUND);
}
return responseEntity;
}
You can make DTO class for response:
public class ResponseDto {
private Shop shop;
private Delear delear;
// getters and setters
}
then
ResponseDto response = new ResponseDto();
response.setShop(shop);
response.setDelear(delear);
And then make your method public ResponseEntity<ResponseDto> getObject...
and return new ResponseEntity<>(response, HttpStatus.OK);

How to list data from database in a web page in spring framework

I have created a database called student base on the tutorial provided by tutorials point PDF, they have covered how to map the form and insert values in to the database using controllers, but they have not explained how to display the data from the database on to the webpage.
My code to list all students.
#Override
public List<Student> listStudents() {
String SQL = "select * from Student";
List<Student> students = jdbcTemplateObject.query(SQL, new StudentMapper());
return students;
}
How to call this from my controller in spring and return the list to my webpage.
My contoller is given below
#Controller
public class StudentController {
#RequestMapping(value = "/student", method = RequestMethod.GET)
public ModelAndView student()
{
return new ModelAndView("student", "command", new Student());
}
#RequestMapping(value = "/addStudent", method = RequestMethod.POST)
public String addStudent(#ModelAttribute("SpringWeb")Student student, ModelMap model)
{
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
StudentJDBCTemplate studentJDBCTemplate = (StudentJDBCTemplate)context.getBean("studentJDBCTemplate");
studentJDBCTemplate.create(student.getName(), student.getAge());
model.addAttribute("name", student.getName());
model.addAttribute("age", student.getAge());
model.addAttribute("msg", "Student Enrolled");
return "result";
}
// How to write the listing controller?
}
From the details you provide ,
public String ListStudents(ModelMap model)
{
List<Student> list= YourServiceClassObj.listStudents();
model.addAttribute("result", list);
return "View Name here";
}
public class AccountDAO {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
public Account getAll(String user, String pass) {
String query = "SELECT * FROM dbo.USERR WHERE username=? AND password =?";
try {
conn = new DBContext().getConnection();
ps = conn.prepareStatement(query);
ps.setString(1, user);
ps.setString(2, pass);
rs = ps.executeQuery();
while (rs.next()) {
return new Account(rs.getString(1),
rs.getString(2),
rs.getString(3));
}
} catch (Exception e) {
}
return null;
}
}
your controller and service methods should be like this .and then in the view use the controller returned attribute students.
#Controller
#RequestMapping(value = "/students", method = RequestMethod.GET)
public String students(ModelMap model)
{
List<Student> students= studentService.getStudents();
model.addAttribute("students", students);
return "student/studentList.html";
}
Service :
public interface StudentService {
List<Student> getStudents();
}
#Service
public class StudentServiceImpl implements StudentService {
#Override
public List<Student> getStudents() {
return studentRepository.findAll();
}

Resources