0

I am new to spring-data, I have this error java.lang.String cannot be cast to com.example.accessingdatamysql.User and do not know how to fix it! I add the various relevant parts of my code.

The method should output the oldest entry (via timestamp) by name.

Main.Controller

package com.example.accessingdatamysql;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller 
@RequestMapping(path="/demo") 
public class MainController {
  @Autowired 
         
  private UserRepository userRepository;

  @Transactional
  @PostMapping(path="/add")
  public @ResponseBody String addNewUser (@RequestParam String name,
          @RequestParam String email,@RequestParam String surname) 
  {
      User n = new User();
      n.setName(name);
      n.setSurname(surname);
      n.setEmail(email);
      userRepository.create(n);
      return "Saved";
  }

  @GetMapping(path="first")
  User one(@RequestParam String name) {
      return userRepository.findFirstByName(name);
  }
}  

User.java

package com.example.accessingdatamysql;

import java.sql.Timestamp;
import java.time.Instant;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity 
public class  User {
  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  private Integer id;
 
  public String name;

  private String email;
  
  private String surname;
  
  @Column(name="stmp", columnDefinition = "TIMESTAMP (6)")
  Timestamp timestamp = Timestamp.from(Instant.now());

  public void setTimestamp(Timestamp timestamp) {
      this.timestamp = timestamp;
  }

  public Timestamp getTimestamp() {
      return timestamp;
  }

  public String getSurname() {
      return surname;
  }
 
  public void setSurname(String surname) {
      this.surname = surname;
  }
 
  public Integer getId() {
      return id;
  }

  public void setId(Integer id) {
      this.id = id;
  }

  public String getName() {
      return name;
  }

  public void setName(String name) {
      this.name = name;
  }

  public String getEmail() {
      return email;
  }

  public void setEmail(String email) {
      this.email = email;
  }
}

RepoImpl.java

package com.example.accessingdatamysql;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

import org.springframework.stereotype.Component;

@Component
public class UserRepositoryImpl implements UserRepository {
    
    private final EntityManager em;
    
    public UserRepositoryImpl(EntityManager entityManager) {
        this.em = entityManager;
    }

    @Override
    public User findFirstByName(String name) {
        CriteriaBuilder builder = em.getCriteriaBuilder();
        CriteriaQuery<User> criteria = builder.createQuery(User.class);
        Root<User> root = criteria.from(User.class);
        criteria.select(root.get("name"));
        criteria.orderBy(builder.asc(root.get("timestamp")));
        TypedQuery<User> query = em.createQuery(criteria).setMaxResults(1);
        return query.getSingleResult();
    }
    
    @Override
//  per la creazione//
    public void create(User entity) {
        em.persist(entity); 
    }   
}

ERROR

 [Request processing failed; nested exception is java.lang.ClassCastException: java.lang.String cannot be cast to com.example.accessingdatamysql.User] with root cause
java.lang.ClassCastException: java.lang.String cannot be cast to com.example.accessingdatamysql.User
        at com.example.accessingdatamysql.UserRepositoryImpl.findFirstByName(UserRepositoryImpl.java:35) ~[classes!/:0.0.1-SNAPSHOT]

2 Answers 2

1

If you meant to find User by name, you should have set the filter parameter not in criteria.select but in criteria.where:

public User findFirstByName(String name) {
    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<User> criteria = builder.createQuery(User.class);
    Root<User> root = criteria.from(User.class); // root is User
    criteria.select(root).where(builder.equal(root.get("name"), name));
    criteria.orderBy(builder.asc(root.get("timestamp")));
    TypedQuery<User> query = em.createQuery(criteria).setMaxResults(1);
    return query.getSingleResult();
}

While criteria.select(root.get("name")); implies that only column "name" is selected and returned, that is the name of the first user should be returned.

If such information is needed, it may be retrieved in the following way:

public String findFirstUserName() {
    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<String> criteria = builder.createQuery(String.class);
    Root<User> root = criteria.from(User.class); // root is User
    criteria.select(root.get("name"));  // getting name 
    criteria.orderBy(builder.asc(root.get("timestamp"))); // of the first/earliest user 
    TypedQuery<String> query = em.createQuery(criteria).setMaxResults(1);
    return query.getSingleResult();
}
Sign up to request clarification or add additional context in comments.

4 Comments

I tried to put the code with "select (root) .where" but when I start it with the get command I get this:D:\>curl -G localhost:8080/demo/first -d name=Biagio {"timestamp":"2020-10-01T19:08:59.425+00:00","status":404,"error":"Not Found","message":"","path":"/demo/first"}
does a User named Biagio exist in your database? As I understand you got rid of ClassCastException with this solution.
Yes, the problem no longer occurs to me but now it no longer finds users. Biagio is in my database but he can't find it .... any ideas? maybe something is missing from the implementation?
You should debug/check the logs of SQL queries, to compare these results to pure SQL SELECT * from User WHERE name='Biagio'
0

Do just like the error says -

CriteriaQuery<String> criteria = builder.createQuery(String.class);

instead of

CriteriaQuery<User> criteria = builder.createQuery(User.class);

Read more here Reference

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.