javaspring-boothibernatetype-mismatch

Java spring boot Hibernate - [type.A] Did not match Query selection type [type.A] multiple selections: use Tuple or array


I moved a Hibrenate implementation to another project. From com.mvc.data to com.mvc.frontend. After moving I get the following exception when trying to fetch data.

org.hibernate.query.QueryTypeMismatchException: Specified result type 
[com.mvc.frontend.enteties.Customer] did not match Query selection type 
[com.mvc.frontend.enteties.Customer] - multiple selections: use Tuple or array

Notice that it's the same type. If I, as suggested by the exception, change the result type to a array, it, as expect, throws the same mismatch exception but with actually mismatching types.

[[Lcom.mvc.frontend.enteties.Customer;] did not match Query selection type 
[com.mvc.frontend.enteties.Customer]

If I change the result type to Tuple, I get a result and it even maps it to the correct type Customer with all 4 variables correctly mapped

list = {ArrayList@12043}  size = 4
 0 = {TupleImpl@12052} "[com.mvc.frontend.enteties.Customer@5fff6af5]"
  tupleMetadata = {TupleMetadata@12134} 
  row = {Object[1]@12135} 
   0 = {Customer@12136} 
    id = {UUID@12137} "95a2adce-7a84-4bda-836d-7de5f135be44"
    name = "Anders Andersson"
    credit = 5000
    created = {Timestamp@12139} "2025-04-09 12:49:58.396667"

Result from the old project with Tuple first and then with Customer as result type, the second result is the desired type.

list = {ArrayList@11076}  size = 4
 0 = {TupleImpl@11083} "[com.mvc.data.enteties.Customer@7ad0ec0e]"
  tupleMetadata = {TupleMetadata@14249} 
  row = {Object[1]@14250} 
   0 = {Customer@14251} 
    id = {UUID@14252} "95a2adce-7a84-4bda-836d-7de5f135be44"
    name = "Anders Andersson"
    credit = 5000
    created = {Timestamp@14254} "2025-04-09 12:49:58.396667"

list = {ArrayList@14435}  size = 4
 0 = {Customer@14428} 
  id = {UUID@14429} "95a2adce-7a84-4bda-836d-7de5f135be44"
  name = "Anders Andersson"
  credit = 5000
  created = {Timestamp@14431} "2025-04-09 12:49:58.396667"

This is how I attempt to fetch the data

public List<Customer> getCustomers() {
  assert Main.sessionFactory != null;

  var session = Main.sessionFactory.openSession();
  if (session != null) {
    var list = session.createSelectionQuery("FROM Customer ORDER BY name", Customer.class).getResultList();
    session.close();
    return list;
  }
  return new ArrayList<>();
}

The class I'm trying to fetch looks like this. It looks exactly the same in the other project with the only exception of the package name.

package com.mvc.data.enteties;

import java.util.Date;
import java.util.UUID;

import jakarta.persistence.*;

@Entity
@Table(name="T_Customer")
public class Customer {

  @Id
  @GeneratedValue
  private UUID id;

  private String name;
  private int credit;
  private Date created;

  // Getters and setters omitted
}

I've tried deleting all tables in the database to let Hibernate regenerate them in the new project and it worked as expected with the same structure being created.

The new project includes MvcConfig, WebSecurityConfig, Devtools, Thymeleaf but I don't see how those packages can affect mapping for Hibernate.


Solution

  • So the problem was that I was using spring-boot-devtools which has a restart function. The restart class loader couldn't find the classes.

    I got the hint when I tried to make a temporary workaround to cast the content of the Tuple to the correct type.

    private <T> T getObject(Tuple tuple, T c) {
      return (T) tuple.get(0);
    }
    

    Then I used it like this

    var customer = session.createQuery("FROM Customer", Tuple.class).getSingleResultOrNull();
    return getObject(customer, new Customer());
    

    Which threw a class loader exception which then led me to the following post with the solution.
    Class loader error - unnamed module of loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader
    Disabling the restart function didn't work for me so I simply removed devtools from Maven.