【问题标题】:QueryDSL projections with @ManyToOne relation具有@ManyToOne 关系的QueryDSL 投影
【发布时间】:2015-02-26 15:10:12
【问题描述】:

我将 OpenJPA 与 QueryDSL 一起使用,我尝试通过使用 QueryDSL 的 bean 投影功能来避免操作 Tuple 对象。例如,我有这两个实体,具有@ManyToOne 关系。

@Entity
public class Folder {
    private Long id;
    private String name;
    private String path;
    @ManyToOne
    @JoinColumn(name = "FK_FILE_ID")
    private File file;
}

@Entity
public class File {
    private Long id;
    private String fileName;
}

当我执行这个查询时:

List<Folder> listFolders = query.from(folder)
.list(Projections.bean(Folder.class, folder.name, folder.file.fileName));

我收到一条错误消息,指出 Folder 对象不包含 fileName 属性。

我了解 QueryDSL 在做什么,因为它是一个简单的“平面”投影,但我想知道是否可以用查询找到的值填充我的 folder.file 对象的 fileName 属性。

注意:我知道我可以为我的 Folder 类定义一个构造函数并使用此方法:

query.list(ConstructorExpression.create(Folder.class, folder.name,
folder.file.fileName));

但如果可能,我想避免这种情况,因为它迫使我为我想要在我的投影中的 N 个字段组合定义 N 个构造函数。

【问题讨论】:

    标签: jpa openjpa dto projection querydsl


    【解决方案1】:

    您可以在这种情况下使用嵌套投影

    List<Folder> listFolders = query.from(folder)
        .list(Projections.bean(Folder.class, folder.name, 
              Projections.bean(File.class, folder.file.fileName).as("file")));
    

    这里是构造函数和 bean 投影的更明确的替代方案,也应该适用于这种情况

    MappingProjection<Folder> mapping = new MappingProjection<Folder>(Folder.class, folder.name, folder.file.fileName) {
     @Override
     protected Folder map(Tuple row) {
         Folder f = new Folder();         
         f.setName(row.get(folder.name));
         File file = new File();
         file.setFileName(row.get(folder.file.fileName));
         f.setFile(file);
         return f;
     }            
    

    };

    相关 http://www.querydsl.com/static/querydsl/3.6.0/apidocs/com/mysema/query/types/MappingProjection.html

    【讨论】:

    • 它对我有用。谢谢!
    猜你喜欢
    • 2020-07-05
    • 2013-12-29
    • 2021-08-27
    • 2021-03-22
    • 1970-01-01
    • 2018-11-05
    • 2022-01-03
    • 2016-03-01
    • 2012-12-06
    相关资源
    最近更新 更多