Join 3 tables in Spring Jpa Data Join 3 tables in Spring Jpa Data spring spring

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 @ManyToOnes and omit the @OneToManys, 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);}