Join 3 tables in Spring Jpa Data
It is more a JPA question.
First, I always emphasize, you are not access "tables". You should view them as domain entities. Lot of misuse of JPA/Hibernate/other ORMs actually comes from direct "translate" of SQL or database concepts.
Back to your question, the answer is simple. First make sure you actually have the "relationships" in your domain entities. Storing IDs is not helping to build a concrete domain model. For example, you have something like :
@Entityclass Series { @Id Long id; @OneToMany(mappedBy="series") List<Dossier> dossiers;}@Entityclass Dossier{ @Id Long id; @ManyToOne Series series; @OneToMany(mappedBy="dossier" List<Item> items;}@Entityclass Item{ @Id Long id; @ManyToOne Dossier dossier;}
The query is straight-forward:
select s.dossiers.items from Series s where s.projectId = :param
Or, if it is more reasonable to have only the @ManyToOne
s and omit the @OneToMany
s, the query is still straight-forward:
from Item where i.dossier.series.projectId = :param
[Still rocky here] Maybe i didn't make myself clear.I know how to express the query in HQL.The problem is to use Spring Data's Specifications,with the help of the criteria api to build that query.
//Let's exampine the following piece of code public class CustomItemSpecs { public static Specification<Item> createSpecificationFromSearchForm(final SearchForm searchForm) { return new Specification<Item>() { @Override public Predicate toPredicate(Root<Item> root, CriteriaQuery<?> query, CriteriaBuilder cb) { CriteriaQuery<Item> cq = cb.createQuery(Item.class); CriteriaQuery<Series> sb = cb.createQuery(Series.class); Root<Series> series = sb.from(Series.class); Join<Series,Dossier> join1 = series.join(Series_.dossiers); Join<Dossier, Item> join2 = join1.join(Dossier_.items); }} }
As you can see i manage to do two seperate joins.The problem is when i want to join Series,Dossier And Items to execute the above query.Notice that join2 is a Dossier-Item set.I can't make criteria like cb.equals(join2.get(Series_.projectId),)
im using spring data interface projection .example like this
note items must be interface class
Repository Class
@Repositorypublic interface ItemRepository extends JpaRepository<Items,Long> { @Query(nativeQuery = true,value = "Select Items from Series,Dossier,Item Where Series.Id=Dossier.seriesId and Dossier.id=Item.dossierId and series.projectId = :param") public Items findTransaksisByAccountIdOrderById(@Param("param") Long projectId);}