I am trying to use JPQL to generate a single SQL statement to fetch multiple different entities all linked to each other with foreign keys.
Model
The model looks like this:
@Entity
@Table(name = "mainentity")
@Data
@IdClass(MainEntityPrimaryKey.class)
public class MainEntity {
@Id
@Column(updatable = false)
private String foo;
@Id
@Column(updatable = false)
private String bar;
@OneToMany(cascade = {CascadeType.ALL}, orphanRemoval = true)
@JoinColumns({
@JoinColumn(name = "foo", referencedColumnName = "foo"),
@JoinColumn(name = "bar", referencedColumnName = "bar")
})
private List<SubEntity> subs;
}
@Entity
@Table(name = "subentity")
@Data
@IdClass(SubEntityPrimaryKey.class)
public class SubEntity {
@Id
@Column(updatable = false)
private String foo;
@Id
@Column(updatable = false)
private String bar;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "first_possibility_id", referencedColumnName = "first_possibility")
private FirstPossibility firstPossibility;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "second_possibility_id", referencedColumnName = "second_possibility")
private SecondPossibility secondPossibility;
}
@Entity
@Table(name = "firstpossibility")
@Data
public class FirstPossibility {
@Id
@Column(name = "first_possibility_id", nullable = false, updatable = false)
private String id;
@Column
private String something;
}
@Entity
@Table(name = "secondpossibility")
@Data
public class SecondPossibility {
@Id
@Column(name = "second_possibility_id", nullable = false, updatable = false)
private String id;
@Column
private String stuff;
}
A SubEntity
will never have both a FirstPossibility
and SecondPossibility
linked at the same time.
Repository
The Spring-Data interface:
public interface MainEntityCRUDRepository extends CrudRepository<MainEntity, MainEntityPrimaryKey> {
@Query("SELECT main FROM MainEntity main WHERE CONCAT(main.foo, '~', main.bar) IN :ids")
List<MainEntity> getAllMainWithConcatenatedIds(@Param("ids") Collection<String> ids);
}
Current state
As it is, it fetches all the MainEntity
properly in a single call to the database (I can see the binding happening correctly with the spring.jpa.show-sql=true
property), but without any SubEntity
.
The SubEntity
get fetched when something ends up trying to access them later in the code, and that also ends up fetching the First
or Second
entities. All of this, with separated DB calls for each entity (which is, performance-wise, something that we want to avoid).
Important note: we use EclipseLink
as our JPA Provider.