Reputation: 67
I wrote this JPQL query and expect a result as List<Question>
:
@Query("SELECT q FROM Question q WHERE q.id IN (SELECT qc.questions FROM QCard qc WHERE qc.id IN (SELECT ct.qCards FROM CTest ct WHERE ct.id=:id))")
These are my classes:
class CTest {
id, List<QCard>
}
class QCard{
id, List<Question>
}
class Question{
id
}
I expected all questions as return for given CTest.id
.
But I got a compiler-error with message:
SQLSyntaxErrorException
I tried use ":" before "select" words but it had not helped.
What is wrong?
Upvotes: 1
Views: 924
Reputation: 9418
Test your SQL query in an SQL-client (e.g. Squirrel, DbVisualizer, etc.).
Assuming your foreign keys are named:
question_id
in table QCard
card_id
in table CTest
you could have an SQL with subselects like:
SELECT q.id
FROM Question q
WHERE q.id IN (
SELECT qc.question_id
FROM QCard qc
WHERE qc.id IN (
SELECT ct.card_id
FROM CTest ct
WHERE ct.id = 1 -- example test id
)
)
Does it return the expected result or are there syntax errors?
Then subsequently replace your subselects by JOIN
s.
SELECT q.id, c.id
FROM Question q
JOIN QCard c ON c.question_id = q.id
SELECT c.id, t.id
FROM QCard c
JOIN CTest t ON t.card_id = c.id
SELECT q.id, c.id, t.id
FROM Question q
JOIN QCard c ON c.question_id = q.id
JOIN CTest t ON t.card_id = c.id
Note: add WHERE
clauses like WHERE t.id = 1
if needed.
Experiment with the FROM/JOIN order as it makes sense.
Then translate the running SQL query to JPQL. For example:
@Query("SELECT q"
+ " FROM CTest test"
// a test has many cards (1:n)
+ " JOIN QCard card ON card.id = test.card_id" // associated cards
// a card has many questions (1:n)
+ " JOIN Question q ON q.id = card.question_id" // associated questions
+ " WHERE test.id = :id")
public List<Question> findQuestionsByTestId(String id);
Upvotes: 1
Reputation: 4592
In your existing query, in inner queries you are selecting entities and checking IN against Id, which will definitely won't work. As you can't complete entry with the Id.
As you haven't shared your complete entity structure, assuming that you have two way relationship declared correctly in entities, here I am placing a reference query which uses the join:
@Query("SELECT q FROM Question q JOIN q.qCard qc WHERE q.qCardId = qc.id AND qc.cTestId = :id")
Where qCardId
is the foreign key reference of QCard
entity in Question
entity and cTestId
is the foreign key reference of CTest
entity in QCard
entity.
You can use this for your reference to update your query with joins.
Upvotes: 1
Reputation: 275
List<Question> findByIdIn(List<Long> idList); //In repository
or
String qlString = "select i from Item i where i.name IN :names";
Query q = em.createQuery(qlString, Item.class);
List<String> names = Arrays.asList("foo", "bar");
q.setParameter("names", names);
List<Item> actual = q.getResultList();
I did those example in my past work, check it, tnx
Upvotes: 0