Join using two different entities in spring data jpa - spring-boot

I have 2 different entities. table1 has a column which is primary key of table2.
both of the tables has respected repository.
If I write below query in one of the repository it gives error
QuerySyntaxException: unexpected token:
#Query("select new stats.UserCountDTO(b.objectiveId, count(b.objectiveId), a.locationCountry)"+
" from UserIdentityEntity a, UserObjectiveEntity b where b.userIdentityId == a.id and b.cId = ?1")
How can I write join queries in this case using spring data jpa?

You just make a mistake. The
b.userIdentityId == a.id
should be:
b.userIdentityId = a.id

Related

Spring JPA join tables without relationship and math operation

I have 2 tables Project_Products(id, product_id, version, name) and Cos_Product(cos_id, version, description)
Now I need to join the tables on Project_Products.product_id = Cos_Product.cos_id and create a column isConflict whose value is going to be 0 or 1 based on if Project_Products.version = Cos_Product.version
Currently I'm running it by using native query using Hibernate Entity Manager. This works perfectly fine by using the query
Select p.id, p.project_id, p.name,
case when p.version = c.version then 0 else 1 as is_conflict
from Project_Products p left join Cos_Product c on p.product_id = c.cos_id
Now how to do this scenario using spring jpa? Without using native query.

Hibernate, Order by count of subquery on ManyToMany using Predicates

I have a query written using Predicates in Hibernate and I need to add a subquery on a join table to count the number of joins and order by the number of joins where they exist in an array of ids.
The join table is a ManyToMany relation.
I am using flyway to setup the table schema, so while the join table exists in the database, a join model is not needed in Hibernate to join the 2 related models therefore no join model exists.
I don't care about retrieving these related models, I just want the number of joins so that I can order by them.
The following is PostGreSQL, which works. I need to convert the following PSQL into a Predicate based query:
SELECT u.*, COUNT(jui.interest_id) AS juiCount
FROM "user" u
LEFT JOIN (
SELECT ui.user_id, ui.interest_id
FROM user_interest ui
WHERE ui.interest_id IN (?)
) AS jui ON u.id = jui.user_id
GROUP BY u.id
ORDER BY juiCount DESC
Where the ids provided for the IN condition are passed into the subquery. The above query is in PostGreSQL.
Working with what I have so far:
CriteriaBuilder b = em.getCriteriaBuilder();
CriteriaQuery<User> q = b.createQuery(User.class);
Root<User> u = q.from(User.class);
// This doesn't make sense because this is not a join table
// Subquery<Interest> sq = q.subquery(Interest.class)
// Root<Interest> squi = sq.from(Interest.class);
// sq.select(squi);
// sq.where(b.in("interest_id", new LiteralExpression<Long[]>((CriteriaBuilderImpl) b, interestIds)));
q.orderBy(
// b.desc(b.tuple(u, b.count(squi))),
b.asc(u.get(User_.id))
);
q.where(p);
return em
.createQuery(q)
.getResultList();
Everything I have managed to find doesn't quite seem to fit right given that they are not using ManyToMany in the use of q.subquery() in their example.
Anyone can help fill in the blanks on this please?

HQL Select New doesn't return row when a foreign key is null

I have the following named query
#NamedQuery(name = "UserFlight.getUserFlightDetails",
query = "SELECT new com.foobar.UserFlightDetails(uf.flight.divertedAirport, uf.flight.number) " +
"FROM UserFlight uf WHERE uf.user.id=?1 AND uf.flight.id=?2")
The UserFlightDetails constructor is as follows
public UserFlightDetails(Airport airport, String flightNumber) {
this.setDivertedAirport(airport);
this.setFlightNumber(flightNumber);
}
divertedAirport is a foreign key in the flight table, path=(uf.flight.divertedAirport)
My problem is when divertedAirport is null (it's a nullable foreign key), my HQL query returns null as the result (The code doesn't even trigger the constructor above), so I don't get the flightNumber which is never null.
If the divertedAirport isn't null, I get both the airport and the flight number fine (and the above constructor gets executed just fine).
What could be causing this and how could I resolve it? I tried some null functions like nullif and coalesce but nothing helped.
I'm using spring boot 1.2.7, hibernate-core 4.3.11.Final
Probably, the problem is the uf.flight.divertedAirport. This expression do a JOIN between flight and divertedAirport but, as you say, divertedAirport is a fk and can be null.
So, you need to use the LEFT JOIN.
I would rewrite your query like this:
#NamedQuery(name = "UserFlight.getUserFlightDetails",
query =
"SELECT new com.foobar.UserFlightDetails(divertedAirport, flight.number)
FROM UserFlight uf
JOIN uf.flight flight
LEFT JOIN flight.divertedAirport divertedAirport
JOIN uf.user user
WHERE user.id = ?1 AND flight.id = ?2 ")
I remove the references like uf.user.id for a explicit JOIN (JOIN uf.user user plus user.id), because is more legible and this kind of problem that generated your question is more easy to find using this way to write JPQL queries.

Select value from grandchildren

I have the following table structure:
I want to select:
all TableA entries + the Identifier column from Table C that have:
a special value in TableBType ("TableBTypeValue")
a special value in TableCType ("TableCTypeValue")
The problem that I have is that the linq queries seem to fail when there are TableA entries that have no TableB entry or if there are TableB entries without a TableC (TableBType and TableCType is mandatory so they don't have that problem).
With SQL this would not be a big problem, but as I am new to linq I could not find the correct way to create this query.
I think this is what you are looking for:
from c in db.TableC
where c.TableCType == TableCTypeValue
join b in db.TableB on c.TableBId equals b.Id
where b.TableBType == TableBTypeValue
join a in db.TableA on b.TableAId equals a.Id
select new { a, c.Identifier };
Hope it helps.

Difference between the LINQ join and sub from

Is there any difference between these two LINQ statements:
var query = from a in entities.A
where a.Name == "Something"
from b in entities.B
where a.Id == b.Id
select b;
var query = from a in entities.A
join b in entities.B on a.Id equals b.Id
where a.Name == "Something"
select b;
Are both statements doing an inner join?
Also how do I view generated the generated SQL statement from the Entity Framework?
This doesn't precisely answer your question, but it's nearly always wrong to use join in LINQ to Entities. Both queries are, in my opinion, incorrect. What you actually want to do in this case is:
var query = from a in entities.A
where a.Name == "Something"
from b in a.Bs // where Bs is the name of the relationship to B on A,
select b; // whatever it's called
You already have the specification of the relationship encoded in your DB foreign keys and your entity model. Don't duplicate it in your queries.
You can get, and compare the SQL for, those queries:
((ObjectQuery)query).ToTraceString();
The generated SQL may be (subtly) different depending on how EF interprets those queries.
FYI- You don't have to include joins when querying related entities.
Logically speaking these two statements are doing the same thing. If they are computed differently by the framework then I would be unimpressed.
Take a look to the sql profiler. You could get your answer.

Resources