原因:org.hibernate.hql.internal.ast.QuerySyntaxException:无法在类上找到适当的构造函数

问题描述

我在存储库中获得的错误

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Unable to locate appropriate constructor on class [com.foxminded.university.dto.LessonDTO]. Expected arguments are: int,java.lang.String,int,java.util.Date,java.lang.String [ SELECT NEW LessonDTO (L.lessonId,L.lessonName,L.classNumber,L.date,T.teacherName,G.groupName) FROM com.foxminded.university.model.Lesson L LEFT JOIN com.foxminded.university.model.Teacher T ON L.teacherId = T.teacherId LEFT JOIN com.foxminded.university.model.Group G ON L.groupId=G.groupId  ORDER BY L.lessonId]

出现错误查询

@Query(" SELECT NEW LessonDTO (L.lessonId," +
    "G.groupName) FROM Lesson L LEFT JOIN Teacher T ON L.teacherId = T.teacherId LEFT JOIN Group G ON " +
    "L.groupId=G.groupId  ORDER BY L.lessonId")
List<LessonDTO> getAllLessonDtos();

LessonDTO类:

@ToString
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class LessonDTO {
@Id
private int id;
private String name;
private intclassNumber;
private Date date;
private String teacherName;
private String groupName;
}

Lesson.class:

@Entity
@ToString
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class Lesson {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer lessonId;
private String lessonName;
private Integer classNumber;
private Timestamp date;
private Integer teacherId;
private Integer groupId;
public Lesson(String lessonName,Integer classNumber,Timestamp date,Integer teacherId,Integer groupId) {
this.lessonName = lessonName;
this.classNumber = classNumber;
this.date = date;
this.teacherId = teacherId;
this.groupId = groupId;
}
}

Group.class:

@Entity
@ToString
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "groups",schema = "public")
public class Group {
@Id
@Column(name="group_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)|
private Integer groupId;
@Column(name="group_name")
private String groupName;
}

Teacher.class:

@Entity
@ToString
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "teachers",schema = "public")
public class Teacher {
@Id
@Column(name="teacher_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer teacherId;
@Column(name = "teacher_name")
private String teacherName;
@Column(name = "position")
private String position;
public Teacher(String teacherName,String position) {
this.teacherName = teacherName;
this.position = position;
}
}

在此应用程序中对StudentDTO的类似方法效果很好:

@Query("SELECT NEW StudentDTO (S.studentId,S.studentName,S.studentSurname,S.studentAge,S.entryYear," +
    "S.graduateYear,S.facultyName,G.groupName) FROM Student S LEFT JOIN Group G ON S.groupId=G.groupId ORDER BY S.studentId")

列出getAllStudentDtos();

如果您需要更多帮助信息,请写信。 预先感谢!

解决方法

解决方法(添加带有 java.util.Date 而不是 java.sql.Timestamp 的构造函数)不可移植且(最重要的是)一点也不直观。

此外,如果它的实体 DTO 无法分配任何与 DB fieldType 不匹配的字段..必须编写单独的 pojo - 不值得

如果查询中有 (SQL) 时间戳,您希望它可以分配给 java.sql.Timestamp。时间戳的精度可以达到纳秒,而 Date 则不是这种情况。 使用如下构造函数并强制转换对象:

public sampleDto(String name,Object lastUpdated) {
  this.name = name;
  this.lastUpdated = (Timestamp) lastUpdated;
}