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.