【问题标题】:JPA Query - no appropriate constructor in class errorJPA Query - 类错误中没有适当的构造函数
【发布时间】:2022-02-21 14:09:16
【问题描述】:

我有一个 Employee 实体类,它有很多列。我想从这个类中获取一些列,因此我使用了 dtos。我创建了一个新的 BaseEmployee 类并在 EmployeeRepository 中编写了查询。但是当我尝试运行应用程序时出现此错误:“类错误中没有适当的构造函数”。

@Entity
@Table(name = "employees")
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonAutoDetect(fieldVisibility = Visibility.ANY)
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "emp_no")
    private  int id;
    @Column(name = "birth_date")   
    private Date birthDate;
    @Column(name = "first_name")
    private String firstName;
    @Column(name = "last_name")
    private String lastName;
    @Column(name = "gender")
    private char gender;
    @Column(name = "hire_date")  
    private Date hireDate;

    @OneToMany(mappedBy = "employees")
    private List<Title> titles; 

    @OneToMany(mappedBy = "employees")
    private List<Salary> salary;

    @OneToMany(mappedBy = "employee")
    private List<DeptEmp> departmentList;

   @OneToMany(mappedBy = "employee")
   private List<DeptManager> managerDepartment;

}

我的 dto 类:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class BaseEmployee {

    private  int id;
    private Date birthDate;
    private String firstName;
    private String lastName;
    private char gender;
    private Date hireDate;

}

Jpa 存储库:

public interface EmployeeRepository extends JpaRepository<Employee,Integer> {
    
    List<Employee> getByFirstNameContains(String firstName);
    List<Employee> getByFirstNameStartsWith(String firstName);


    @Query("Select new dev.serhat.employeeapi.models.dtos.BaseEmployee"
    + "(e.id, e.birthDate, e.firstName, e.lastName, e.gender, e.hireDate) From Employee e WHERE e.id = :id")
    Optional<BaseEmployee> getBaseEmployeeById(int id);
    
    
}

错误:

HH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
2022-02-20 16:33:42.533  INFO 24371 --- [  restartedMain] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2022-02-20 16:33:42.559  INFO 24371 --- [  restartedMain] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2022-02-20 16:33:43.431 ERROR 24371 --- [  restartedMain] o.h.hql.internal.ast.ErrorTracker        :  Unable to locate appropriate constructor on class [dev.serhat.employeeapi.models.dtos.BaseEmployee]. Expected arguments are: int, java.util.Date, java.lang.String, java.lang.String, char, java.util.Date
[cause=org.hibernate.PropertyNotFoundException: no appropriate constructor in class: dev.serhat.employeeapi.models.dtos.BaseEmployee]
2022-02-20 16:33:43.443 ERROR 24371 --- [  restartedMain] o.h.hql.internal.ast.ErrorTracker        :  Unable to locate appropriate constructor on class [dev.serhat.employeeapi.models.dtos.BaseEmployee]. Expected arguments are: int, java.util.Date, java.lang.String, java.lang.String, char, java.util.Date
[cause=org.hibernate.PropertyNotFoundException: no appropriate constructor in class: dev.serhat.employeeapi.models.dtos.BaseEmployee]

org.hibernate.hql.internal.ast.DetailedSemanticException: Unable to locate appropriate constructor on class [dev.serhat.employeeapi.models.dtos.BaseEmployee]. Expected arguments are: int, java.util.Date, java.lang.String, java.lang.String, char, java.util.Date
        at org.hibernate.hql.internal.ast.tree.ConstructorNode.resolveConstructor(ConstructorNode.java:182) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final]

【问题讨论】:

    标签: java spring-boot hibernate spring-data-jpa dto


    【解决方案1】:

    Lombok 生成的全参数构造函数调用java.util.Date 类型的两个参数。

    当 hibernate 执行你的 jpql 时,它在构造函数中使用 org.hibernate.type.TimestampType 对象而不是 java.util.Date 对象。当然没有生成这样的构造函数,因此错误。

    这里是关于如何处理这种情况的堆栈溢出讨论:How to force Hibernate to return dates as java.util.Date instead of Timestamp?

    【讨论】:

    • 我在 Employee 类和 BaseEmployee 中使用了 java.sql.Date。当我在 BaseEmployee 中将 java.sql.Date 更改为 java.util.Date 时,它起作用了。我刚开始学习spring web :) 我认为java.sql.date 可以在两个类中工作。谢谢你:)
    【解决方案2】:

    错误很简单,您的类BaseEmployee 缺少执行getBaseEmployeeById() 所需的适当构造函数。您的类使用 @NoArgsConstructor@AllArgsConstructor 注释,但这些是 Spring 可能无法识别的 lombok 注释。您的方法getBaseEmployeeById() 需要一个显式定义的具有以下签名的构造函数:

    public BaseEmployee(int id, Date birthDate, String firstName, String lastName, char gender, Date hireDate)
    

    目前缺少这样的构造函数。

    请在您的类中添加一个具有所述签名的构造函数,然后重试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-24
      • 1970-01-01
      • 2021-05-08
      • 2014-09-25
      • 1970-01-01
      • 2022-10-14
      • 2022-08-15
      相关资源
      最近更新 更多