Let me share my approach and solution.
The repository code for the above query is as follows:
- Let's create two Entities corresponding to our tables.
import javax.persistence.*;
@Entity
@Table(name = "questions")
public class Question {
@Id
private String id;
private String description;
// Getters and setters...
}
@Entity
@Table(name = "questions_workflow")
public class QuestionWorkflow {
@Id
@Column(name = "business_id")
private String businessId;
@ManyToOne(targetEntity = Question.class)
@JoinColumn(name = "parent_id", referencedColumnName = "id")
private Question parentQuestion;
@ManyToOne(targetEntity = Question.class)
@JoinColumn(name = "child_id", referencedColumnName = "id")
private Question childQuestion;
// Getters and setters...
}
- Now, create a class to hold the result of our query.
public class CustomResult {
private String businessId;
private String parentId;
private String parentDescription;
private String childId;
private String childDescription;
public CustomResult(String businessId, String parentId, String parentDescription, String childId, String childDescription) {
this.businessId = businessId;
this.parentId = parentId;
this.parentDescription = parentDescription;
this.childId = childId;
this.childDescription = childDescription;
}
// getters and setters...
}
- Now, let's create our JPA repository:
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface QuestionWorkflowRepository extends JpaRepository<QuestionWorkflow, String> {
@Query("SELECT new com.yourpackage.CustomResult(a.businessId, a.parentQuestion.id, a.parentQuestion.description, a.childQuestion.id, a.childQuestion.description) " +
"FROM QuestionWorkflow a " +
"WHERE a.businessId = ?1")
List<CustomResult> findByBusinessId(String businessId);
}
Here, you need to replace com.yourpackage
with your actual package name.
Remember that in JPQL, the join operations are performed based on the object model, not the database tables. Hence, we don't need to explicitly mention "INNER JOIN" operations in the @Query annotation for ManyToOne relationships. In the above query, "a.parentQuestion.description" will automatically fetch the description from the Question entity that's joined via the parent_id and similar for childQuestion. The returned results will be wrapped in CustomResult objects and returned as a list.
Remember to mark your foreign key columns with @ManyToOne and @JoinColumn annotations in your entity classes. The @JoinColumn annotation defines the actual physical mapping on the database table.
Hope this answer would be helpful.