I have the following entities in my spring boot app, which is serving an API for a front end:
@Entity
public class Company {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_company")
@SequenceGenerator(name = "seq_company", allocationSize = 1)
@Column(nullable = false, updatable = false)
private Long id;
private String name;
private String shortName;
}
@Entity
public class Plant {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_plant")
@SequenceGenerator(name = "seq_plant", allocationSize = 1)
@Column(nullable = false, updatable = false)
private Long id;
private String code;
private String location;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="companyid", nullable = false)
private Company company;
}
@Entity
public class PlantArea {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_plantarea")
@SequenceGenerator(name = "seq_plantarea", allocationSize = 1)
@Column(nullable = false, updatable = false)
private Long id;
private String code;
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="plantid", nullable = false)
private Plant plant;
}
Each company
can have one or more plants
and each plant
can have one or more plantareas
. Notice, that I don't have any List
properties in the entities, this is not needed.
For querying the entities I use @EntityGraph
in order to avoid the famous n+1 select problem.
This is how I get all plants in the repository interface:
@EntityGraph(type = EntityGraph.EntityGraphType.FETCH, attributePaths = {"company"})
List<Plant> findAll();
Since the API needs the related company
entity, I fetch it. With this I get what I want, it's all fine.
Now, this is how I get all plant areas:
@EntityGraph(type = EntityGraph.EntityGraphType.FETCH, attributePaths = {"plant", "plant.company"})
List<PlantArea> findAll();
Notice the plant.company
attribute path. With this I get obviously the full chain of entities: plantarea
-> plant
-> company
. This works too.
But for the front end if I query for all plant areas, I don't need the related company
entities, just the plant
entities. But if I remove the plant.company
attribute path, I get the following error pointing to the company
property in the plant
entity:
No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer
I googled this and can resolve this, if I put this line of code (annotate the company
property) in the plant
entity:
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
But in this case I get the n+1 select problem and on top I get the related company
entities too (which I don't want).
So, the question is: how can I select all plantarea
entities with the related plant
entity, but without the related company
entity? And all that without using the above @JsonIgnoreProperties
annotation.