Exclude certain attributes with JPA @EntityGraph

1.3k Views Asked by At

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?

1

There are 1 best solutions below

2
On

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);