Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate CriteriaBuilder to join multiple tables

Tags:

I'm trying to join 4 tables using hibernate criteriabuilder..
Below are the tables respectively.. `

@Entity public class BuildDetails {     @Id     private long id;     @Column     private String buildNumber;      @Column     private String buildDuration;     @Column     private String projectName;  }     @Entity public class CodeQualityDetails{     @Id     private long id;     @Column     private String codeHealth;     @ManyToOne     private BuildDetails build; //columnName=buildNum }  @Entity public class DeploymentDetails{     @Id     private Long id;     @Column     private String deployedEnv;     @ManyToOne     private BuildDetails build; //columnName=buildNum }  @Entity public class TestDetails{     @Id     private Long id;     @Column     private String testStatus;     @ManyToOne     private BuildDetails build; //columnName=buildNum } 


In these 4 tables I would like to perform the below sql script for MySQL:

SELECT b.buildNumber, b.buildDuration,        c.codeHealth, d.deployedEnv, t.testStatus FROM BuildDetails b INNER JOIN CodeQualityDetails c ON b.buildNumber=c.buildNum INNER JOIN DeploymentDetails d ON b.buildNumber=d.buildNum INNER JOIN TestDetails t ON b.buildNumber=t.buildNum WHERE b.buildNumber='1.0.0.1' AND       b.projectName='Tera' 

So, How can I achieve this using Hibernate CriteriaBuilder? Please help...

Thanks in advance.......

like image 471
ktgirish Avatar asked Feb 01 '17 15:02

ktgirish


People also ask

How can we join multiple tables in hibernate criteria?

Criteria in Hibernate can be used for join queries by joining multiple tables, useful methods for Hibernate criteria join are createAlias(), setFetchMode() and setProjection() Criteria in Hibernate API can be used for fetching results with conditions, useful methods are add() where we can add Restrictions.

What is CriteriaBuilder in hibernate?

Interface CriteriaBuilder. public interface CriteriaBuilder. Used to construct criteria queries, compound selections, expressions, predicates, orderings. Note that Predicate is used instead of Expression<Boolean> in this API in order to work around the fact that Java generics are not compatible with varags.


1 Answers

CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery query = cb.createQuery(/* Your combined target type, e.g. MyQueriedBuildDetails.class, containing buildNumber, duration, code health, etc.*/);  Root<BuildDetails> buildDetailsTable = query.from(BuildDetails.class); Join<BuildDetails, CopyQualityDetails> qualityJoin = buildDetailsTable.join(CopyQualityDetails_.build, JoinType.INNER); Join<BuildDetails, DeploymentDetails> deploymentJoin = buildDetailsTable.join(DeploymentDetails_.build, JoinType.INNER); Join<BuildDetails, TestDetails> testJoin = buildDetailsTable.join(TestDetails_.build, JoinType.INNER);  List<Predicate> predicates = new ArrayList<>(); predicates.add(cb.equal(buildDetailsTable.get(BuildDetails_.buildNumber), "1.0.0.1")); predicates.add(cb.equal(buildDetailsTable.get(BuildDetails_.projectName), "Tera"));  query.multiselect(buildDetails.get(BuildDetails_.buildNumber),                   buildDetails.get(BuildDetails_.buildDuration),                   qualityJoin.get(CodeQualityDetails_.codeHealth),                   deploymentJoin.get(DeploymentDetails_.deployedEnv),                   testJoin.get(TestDetails_.testStatus)); query.where(predicates.stream().toArray(Predicate[]::new));  TypedQuery<MyQueriedBuildDetails> typedQuery = entityManager.createQuery(query);  List<MyQueriedBuildDetails> resultList = typedQuery.getResultList(); 

I assume you built the JPA metamodel for your classes. If you don't have the metamodel or you simply don't want to use it, just replace BuildDetails_.buildNumber and the rest with the actual names of the column as String, e.g. "buildNumber".

Note that I could not test the answer (was also writing it without editor support), but it should at least contain everything you need to know to build the query.

How to build your metamodel? Have a look at hibernate tooling for that (or consult How to generate JPA 2.0 metamodel? for other alternatives). If you are using maven it can be as simple as just adding the hibernate-jpamodelgen-dependency to your build classpath. As I do not have any such project now available I am not so sure about the following (so take that with a grain of salt). It might suffice to just add the following as dependency:

<dependency>   <groupId>org.hibernate</groupId>   <artifactId>hibernate-jpamodelgen</artifactId>   <version>5.3.7.Final</version>   <scope>provided</scope> <!-- this might ensure that you do not package it, but that it is otherwise available; untested now, but I think I used it that way in the past --> </dependency> 
like image 103
Roland Avatar answered Sep 21 '22 10:09

Roland