我有一个与描述的jooq query nested object个问题非常相似的问题.总而言之,我有这样一个POJO:

public class CourseComposite {
  private String courseName;
  private Teacher teacher;
  private List<Student> students;
  ...
}

我使用Jooq DefaultRecordMapper将记录映射到POJO,查询如下:

    ctx().select(
            COURSE.NAME.as("courseName"), 
            TEACHERS, 
            multiset(selectFrom(STUDENT).where(STUDENT.ID_COURSE.eq(COURSE.ID))).as("students")
          )
          .from(COURSE).innerJoin(TEACHERS).on(COURSE.ID.eq(TEACHER.ID_COURSE))
          .where(...)
          .fetchInto(CourseComposite.class);

但是,教师没有映射(教师字段为空).我想这是因为我的PostgreSQL表名为teachers而不是teacher(这是上面提到的堆栈溢出问题的唯一区别).

我试着写道:

ctx().select(COURSE.NAME.as("courseName"), TEACHERS.as("teacher"), multiset(...))

然而,在本例中,我得到了一个例外:

表"Teacher"缺少FROM-子句条目

有没有办法告诉jooq应该将TEACHERS绑定到Teacher teacher对象?

推荐答案

这是"意料之中的",尽管无可否认,这有点奇怪,因为您实际上是在混淆Table,而不是SelectField(API是相同的).对于jOOQ来说,您在SELECT子句中为该特定目的别名TEACHERS.as("teacher") only这一事实是未知的.您也可以像使用任何其他表别名一样使用别名.这样想吧:

Teachers teacher = TEACHERS.as("teacher");

现在,您将按如下方式使用它:

ctx().select(..., teacher, ...)

JOOQ不能简单地假设您的意思是让别名在SELECT子句中应用only.如果您也将其添加到您的FROM子句中,如PostgreSQL的错误消息所示,会怎么样?即.

innerJoin(teacher)

因为这样一来,投影teacher别名引用而不是TEACHERS表引用将是有意义的.您可能会争辩说,jOOQ可以检测出什么是正确的东西™,因为您显然没有在第FROM子句中包括teacher,但可能有许多边缘情况,特别是当您两者都有的时候(通过自联接).

因此,解决方案是在FROM子句中只使用teacher,而不是TEACHERS.

替代方案

显然,您可以使用ad-hoc converter将映射移动到查询中,至少部分移动到查询中,从而解决这个问题.你可以写道:

TEACHERS.convertFrom(r -> r.into(Teacher.class))

在这种情况下,从TeachersRecordTeacher类的映射将发生before,试图将嵌套的记录映射到父对象.同样值得考虑的是完全删除基于反射的DefaultRecordMapper,并将对象转换为记录:

public record CourseComposite(
  String courseName, 
  Teacher teacher, 
  List<Student> students
) {}

现在,您可以在查询末尾使用fetchInto(Records.mapping(CourseComposite::new)),所有类型都是安全的!

Java相关问答推荐

如果它最终将被转换为int类型,为什么我们在Java中需要较小的integer类型?

找到允许的最大底片

Java取消任务运行Oracle查询通过JDBC—连接中断,因为SQLSTATE(08006),错误代码(17002)IO错误:套接字读取中断

Javascript在边界中心调整ImageView大小

Java List with all combinations of 8 booleans

Java记录的不同序列化/反序列化

调用引发泛型异常的泛型方法时出现编译错误

SpringBoot+Java 17@Valid未验证POJO

将java.util.Date转换为OffsetDateTime

MySQL数据库中未应用具有Spring数据的唯一约束

S,要对Java复制构造函数深度克隆所有属性进行单元测试,最可靠的方法是什么?

使用存储在字符串变量中的路径目录打开.pdf文件

如何从日志(log)行中删除包名称?

如何使用log4j2(Json)记录由";异常引起的所有";?

如何在太阳系模拟器中添加月球?

Regex以查找不包含捕获组的行

一对多关系和ID生成

持续时间--为什么在秒为负数的情况下还要做额外的工作?

在权限列表中找不到我的应用程序

MapStruct记录到记录的映射不起作用