Querying for a second level entity in Spring with JPA and there is no error, the web page sits on spinning wheel loading, and the debugger window shows the query, but no error.
The top-level entity is Health Check
, and I am trying to retrieve a list of entities extended by Task
with it.
Health Check
@Entity
@Data
@Table(name="HEALTH_CHECK")
public class HealthCheck {
@Id
@GeneratedValue(strategy = IDENTITY)
private Long healthCheckid;
@JsonManagedReference
@ManyToOne(fetch = FetchType.EAGER, optional = false)
private Bird bird;
@JsonBackReference
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy="healthCheck")
private List<Task> tasks;
}
Task
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@DiscriminatorColumn(name = "TASK_TYPE")
@Table(name="TASK")
public class Task {
@Id
private Long taskId;
@JsonManagedReference
@ManyToOne(fetch = FetchType.LAZY, optional = false)
private HealthCheck healthCheck;
}
Various entities extend Task
like PIT
, MEM
and XMIT
- only PIT
shown here for berevity:
PIT
@Entity
public class PIT extends Task {
@Column(unique = true)
@NotEmpty(message = "Name must not be null or empty")
private String code;
@JoinColumn(name ="date_instered")
private LocalDate dateInserted;
@OneToOne(fetch = FetchType.LAZY, optional = true)
private HealthCheck healthCheck;
@Lob
private String comment;
}
NB PIT is one of four extended classes using Task. I have tried to query for a Health Check
with all associated tasks in the following query, but this just gives Health Check
details.
public interface HealthCheckRepository extends JpaRepository<HealthCheck, Long> {
@Query("SELECT h FROM HealthCheck h JOIN FETCH h.tasks t WHERE h.healthCheckid = :id")
Optional<HealthCheck> getFullHealthCheck(@Param("health_check_id") Long id);
}
In plain english, I want to get a specific HealthCheck
and the associated id of Task. If any of the extended classes of PIT
MEM
XMIT` are also present (in there own tables) they will share the same Id as task (in the above query it would be t.id). Part of the answer is to do with TYPE in the query like here.
How can I include fields from the child classes like PIT
where there is a record?
We have discussed it on chat and I was able to reproduce your settings. There are some issues with your code:
@JsonBackReference
annotation in the HealthCheck
entity cause the field tasks
to not being serialized. Hence not present in JSON at all. You should swap both annotations around like this:// in HealthCheck
@JsonManagedReference
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy="healthCheck")
private List<Task> tasks;
// in Task
@JsonBackReference
@ManyToOne(fetch = FetchType.LAZY, optional = false)
private HealthCheck healthCheck;
healthCheck
not only in the Task
entity but also in the PIT
entity. With different meaning. As this field is in use for mapping of tasks this cause an issue while Hibernate is fetching and mapping the entities. Most probably you don't need the second field. Either remove or rename it.Table HEALTH_CHECK: (health_check_id)
(1)
Table TASK: empty! (you have no entities of type Task)
Table PIT: (task_id, health_check_id)
(1, 1)
(2, 1)
This means two PITs (with ID 1 and 2) related to the HEALTH_CHECK with ID=1.