Java – hibernate criteriabuilder connects multiple tables
I'm trying to add four tables using hibernate criteriabuilder
@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 four tables, I want to execute the following 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 do I use hibernate criteriabuilder to achieve this goal? Please help
Thank you in advance
Solution
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
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,TestDetails> testJoin = buildDetailsTable.join(TestDetails_.build,JoinType.INNER); List<Predicate> predicates = new ArrayList<>(); predicates.add(cb.equal(BuildDetails_.buildNumber,"1.0.0.1")); predicates.add(cb.equal(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 suppose you build a JPA Metamodel for your class If you don't have a metamodel or you don't want to use it at all, just put build details_ Replace buildnumber with the rest, and replace the actual name of the column with string, for example: "buildnumber"
Please note that I can't test the answer (also write it without editor support), but it should contain at least everything I need to know to build the query
How to build a meta model? Check out hibernate tooling (or other alternatives, please consult how to generate JPA 2.0 metamodel?) If you are using maven, it is as simple as adding hibernate JPA model Gen dependency to the build classpath Because I don't have any such projects now, I'm not sure about the following contents (so please wait a minute) It may be sufficient to add the following as dependencies:
<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>