使用 JPA @EntityGraph 排除某些属性

发布于 2025-01-11 18:26:41 字数 1336 浏览 0 评论 0原文

我有一个名为 Program 的类,其中包含一组文件(和其他基本属性),作为其自己的类 ProgramFile 实现,表示 的多值复合属性>关系模型中的程序。我将 Spring Boot 与 Hibernate 一起使用。

ProgramFile的集合在Program中实现如下:

...
@ElementCollection
@CollectionTable(
        name = "GPI_PROGRAMAS_FICHEROS",
        joinColumns = @JoinColumn(name = "ID_PROGRAMA")
)
private Set<ProgramFile> files;
...

ProgramFile的代码为:

@Embeddable
public class ProgramFile {

    @Column(name = "NOMBRE_FICHERO")
    private @NonNull String fileName;

    @Lob
    @JsonIgnore
    @Basic(fetch = FetchType.LAZY)
    @Column(name = "FICHERO")
    private byte[] file;
}

ProgramFile.file are large PDF 文件,我的目标是将 Program 序列化为 JSON。为了避免 N+1 问题,我使用 @EntityGraph 来提示 Hibernate 仅执行一个 SQL 查询来检索所有数据:

@EntityGraph(
        type = EntityGraph.EntityGraphType.LOAD,
        attributePaths = {
                "files"
        }
)
List<Program> findAll(Specification<Program> spec);

我面临的问题是我只对 ProgramFile.fileName 感兴趣/code>,不在 ProgramFile.file 中。因为后者是大文件,所以 SQL 查询会非常慢,而且我不希望该属性包含在 JSON 中。

问题:有什么方法可以指示 Hibernate 不获取 ProgramFile.file 或实现排除它的 JSON 序列化的替代方法吗?

I have a class called Program which contains a set of files (and other basic attributes), implemented as its own class ProgramFile, representing a multi-valued composite attribute of Program in the relational model. I'm using Spring Boot with Hibernate.

The set of ProgramFile is implemented as follows in Program:

...
@ElementCollection
@CollectionTable(
        name = "GPI_PROGRAMAS_FICHEROS",
        joinColumns = @JoinColumn(name = "ID_PROGRAMA")
)
private Set<ProgramFile> files;
...

The code of ProgramFile is:

@Embeddable
public class ProgramFile {

    @Column(name = "NOMBRE_FICHERO")
    private @NonNull String fileName;

    @Lob
    @JsonIgnore
    @Basic(fetch = FetchType.LAZY)
    @Column(name = "FICHERO")
    private byte[] file;
}

ProgramFile.file are large PDF files and my goal is to serialize Program to JSON. In order to avoid the N+1 problem I'm using @EntityGraph to hint Hibernate at performing only one SQL query to retrieve all data:

@EntityGraph(
        type = EntityGraph.EntityGraphType.LOAD,
        attributePaths = {
                "files"
        }
)
List<Program> findAll(Specification<Program> spec);

The problem I'm facing is that I'm only interested in ProgramFile.fileName, not in ProgramFile.file. Because the latter are large files the SQL query will be very slow and I don't want that attribute to be included in the JSON.

Question: Is there any way to indicate Hibernate NOT to fetch ProgramFile.file or an alternative to achieve JSON serialization excluding it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

痴骨ら 2025-01-18 18:26:41

您可以尝试以下解决方案:

  1. 将命名图添加到根实体(程序)
@NamedEntityGraphs({
        @NamedEntityGraph(
                name = "program-without-filecontent",
                attributeNodes = {
                        @NamedAttributeNode(value = "files", subgraph = "program-files")
                },
                subgraphs = {
                        @NamedSubgraph(
                                name = "program-files",
                                attributeNodes = {
                                        @NamedAttributeNode(value = "fileName")
                                }
                        )
                }
        )
})
@Entity
class Program { 
...
  1. 在存储库中使用此命名图:
@EntityGraph(value = "program-without-filecontent", type = EntityGraph.EntityGraphType.LOAD)
List<Program> findAll(Specification<Program> spec);

You can try following solution:

  1. Add Named graph to root entity (Program)
@NamedEntityGraphs({
        @NamedEntityGraph(
                name = "program-without-filecontent",
                attributeNodes = {
                        @NamedAttributeNode(value = "files", subgraph = "program-files")
                },
                subgraphs = {
                        @NamedSubgraph(
                                name = "program-files",
                                attributeNodes = {
                                        @NamedAttributeNode(value = "fileName")
                                }
                        )
                }
        )
})
@Entity
class Program { 
...
  1. Use this Named graph in repository:
@EntityGraph(value = "program-without-filecontent", type = EntityGraph.EntityGraphType.LOAD)
List<Program> findAll(Specification<Program> spec);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文