Skip to content

Failed to convert from type [java.lang.Object[]] to type [@org.springframework.data.jpa.repository.Query com.data.models.Users]

I am trying to limit my query to only select specific columns from a table which am going to use, but when I write a simple select query I end up with an error

Resolved [org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.Object[]] to type [@org.springframework.data.jpa.repository.Query com.aims.covidsurvey.models.Users] for value ‘{44, [email protected], John , Smith}’; nested exception is org.springframework.core.convert

When I select all, no errors but it picks some big columns that take the query take long to execute.

This is what I have done so far

my repository

public interface ProductRepository extends JpaRepository<Users, Long> {
    
    @Query("SELECT p FROM Users p WHERE CONCAT(p.id, ' ', p.email, ' ', p.firstname, ' ', p.surname) LIKE %?1%")
     List<Users> search(String keyword);

    @Query("SELECT e.id, e.email, e.firstname, e.surname FROM Users e")
     List<Users> findByQuery();
}

My service

@Service
public class ProductService {
    @Autowired
    private ProductRepository repo;



    public List<Users> listAll(String keyword) {
        if (keyword != null) {
            return repo.search(keyword);
        }
        return repo.findByQuery();
    }
}

My model class

@Entity
@Table(name = "users")
public class Users {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotBlank
    @Size(max = 100)
    private String username;

    @NotBlank
    @Size(max = 100)
    @Email
    private String email;

    @NotBlank
    @Size(max = 120)
    private String password;

    private String surname;
    private String firstname;
    @Lob
    private byte[] data;
    private Date datecreated;
    private String date_of_birth;
    @Size(max = 10)
    private String gender;
    @Size(max = 30)
    private String national_id;
    @Size(max = 120)
    private String study_role;
    @Size(max = 20)
    private String assigned_team;
    private Integer active;
    private Date  activation_date;
    private String trainingvenue;
    private String staffid;
    private String trainingclass;
    private String country;
    private String resetPasswordToken;
    private Integer deleted;

    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    private String userid;

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "user_roles",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set<Role> roles = new HashSet<>();

    public Users() {
    }

    public Users(Long id, String email, String firstname, String surname) {
        this.id = id;
        this.email = email;
        this.surname = surname;
        this.firstname = firstname;

    }

My controller

@RequestMapping("/")
public String viewHomePage(Model model, @Param("keyword") String keyword) {
   // List<Users> listProducts = service.listAll(keyword);
    List<Users> listProducts = service.listAll(keyword);

    model.addAttribute("listProducts", listProducts);
    model.addAttribute("keyword", keyword);

    return "index";
}

What am I doing wrong?

Thank you in advance.

Answer

The problem is in your repository. When you only select some columns, Spring Boot cannot convert them into your Users object.

There are 2 ways to fix this:

1. Change the return type to List<Object[]>.

@Query("SELECT e.id, e.email, e.firstname, e.surname FROM Users e")
List<Object[]> findByQuery();

Then, you have to do the mapping yourself.

2. Change the query

@Query("SELECT new Users(e.id, e.email, e.firstname, e.surname) FROM Users e")
List<Users> findByQuery();

Just make sure that you have the appropriate constructor in your Users model. As I see, you already have it.

In my opinion, this is a more elegant approach.