Run complex SQL Query with spring boot repositories - spring

i have a little complex scenario using spring data and jpa currently.
My data structure is like:
And i like to create a filter: give me all events which belongs to a list of structures, within a given period and is assigned to a list of categories.
I was able to create a sample SQL statement:
select * from event e inner join period p on e.period_id=p.id
inner join category_item_ids ci on e.id=ci.item_ids
inner join category c on ci.category_id=c.id
inner join event_assignment_structure_ids es on es.event_assignment_id=e.id
where p.start between '2020-05-01 12:00:00.000000' and '2020-11-14 12:00:00.000000' and
c.id in (1) and
es.structure_ids in (1,2)
But my objects are currently not wired together by all the JPA annotations.
e.g. the "Same ID" is something i did by convention to make the parts a little more independend.
So using the JPA way is currently no option i guess due to the missing relations.
Introducing them will be also quite a lot of work.
So i was wondering if there is a possiblity to run the sql query directly (i could use native query, but thats also no option, cause the filter values are not always given, so i need 13 native queries)
I used enityManager and query Builder in the past, but thats also no option due to the missing jpa relations.
Any ideas are much welcome :-)
Regards
Oliver

Related

How to make left join on two un-related tables in hibernate query

I am trying to write a left join in hibernate query. I am not able to finish it because the two tables have no relationship.
How to make left join query in hibernate query?
If the tables have no relationship how do you expect to join them? They have to be related somehow.
Basically you need to join ON SOMETHING, if you just want data from both tables then you can query them separately.
Some more information is definitely warranted here.
Anywho, pretending that we have two tables TA and TB, if TA is connected to TB as a TA.tbData where tbData is a #OneToMany relationship, you can do something similar to:
You should have your Root from TA, let's call it here rootTA.
Join<TA, TB> fromTA = rootTA.join('tbData', JoinType.LEFT);
// your business logic here
Either way, this is very generic, without any code information or telling us what you tried, it means next nothing.
You can use DetachedCriteria that performs subquery
an example follows
DetachedCriteria personCriteria = DetachedCriteria.forClass(Person.class);
personCriteria.setProjection(Property.forName("id"));
personCriteria.add(Restrictions.eq("personLastName", "Smith"));
Criteria criteria = getSession().createCriteria(Account.class);
criteria.add(Property.forName("personId").in(personCriteria));

Optimizing Hibernate layer

After moving the logic from a legacy application (SQL/coldfushion) to Spring Rest with Hibernate, we have experienced a slowness in the application. The main reason is with Hibernate we noticed many queries are generated which we used to do with one single query in the legacy application (two pages long query).
Write now, I'm looking at selecting proper fetch strategies and try to optimize code. Could you please give me any other areas that I need to investigate to optimize the Hibernate layer or any other sujjestions?
Try to use DTO not entities(you can load DTO directly from the database)
Review the loading strategy (Eager or Lazy)
Try to use Native Queries more
Try to use more parameters to restrict the result set
You also can leverage some caching technique (cache all static data)
Try to implement hashCode and equals for each entity
If you use, HQL queries, then add the 'join fetch', It avoids the n+1 query problems. For more information on join fetch
e.g:
select a from Model a
inner join fetch a.b as b
Add 'indexes' for columns which are using in where condition.
e.g: Add index for the column 'name' which is used in where condition.
select a from Model a where a.name ='x'
Follow the below links:
http://www.thoughts-on-java.org/tips-to-boost-your-hibernate-performance/
https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/performance.html

Left Join 1 to 1/0 with llblgen?

With EF, if you navigate to a singular related entity within a select projection(such as from the many side of a many-to-one or 1-to-1/0) it would coalesce nulls and give you a left join: https://stackoverflow.com/a/2525950/84206
Since it occurs in a project and not in a join, EF makes a pretty reasonable assumption that a left join is desired.
However, I haven't found a way to accomplish this in LINQ with LLBLGen. The above technique produces an inner join with LLBGen. I can't use techniques that use DefaultIfEmpty because that's only available when navigating into a many relationship.
I am hoping to avoid using WithPath/Prefetch because I'd really like to do the projection in LINQ instead of grabbing a huge object graph into memory and do the projection in memory.
This is LLBLGen 3.5.
If the FK is nullable, the join will be a left join. If the FK isn't nullable, it will be an inner join. This is the only way it's determinable what you want as Linq lacks any other system to specify the join type in this. Your link must use a nullable (optional) FK side as well to get a left join.
If nothing helps, please use queryspec, the query api will allow you to specify the join type in any case.
ps: please next time post on our forums, we don't monitor SO every day, but we do monitor our forums.

Codeigniter active record nested select issue

I am using codeigniter for my php project, but am not much experience in it. So, please help me.
I have two database. 1. Kalix2 2. Asterisk
In both the database I am having some table. I want to make a join on the tables from two different database. I have the below query, it's working fine in back-end, but I don't know how to implement it using Active record.
SELECT a.CompanyName, sum(ceil((b.billsec)/(c.Call_Limit*60))) as totalcall,
hour(b.calldate) as use_hour FROM Kalix2.ph_Companies a
INNER JOIN Asterisk.cdr b ON b.clid LIKE CONCAT('%', a.CompanyName, '%')
INNER JOIN Kalix2.ph_Plans c ON c.Comp_ID= a.Comp_ID
where date(b.calldate)>='2013-01-15' and date(b.calldate)<='2013-1-20'
and c.Plan_Type='Per_Call' and a.CompanyName='ABCD'
group by hour(b.calldate);
Please help me to convert this query into active record format.
You should be able to convert this to active record if you want but you will gain better performance by just converting this to Query Bindings. Common mistake is trying to run a query off of multiple classes:
$this->db1
$this->db2
This will not work because running $this->db1->get() because it is only aware of the data in db1 and not db2. Verbosely keep the database.table info in the joins, use only one db object, and use the profiler to debug the query generation and you should be good.
Connecting to Multiple Databases
Active Record Class and Joins
Debug the query using Profiler

When to use JOIN and when not to in LINQ to entities

I am new to Linq and I have seen that if there are multiple entities, some use the multiple FROM syntax like this:
from h in db.Hubs
from ch in h.CityHubs where ch.Cities.CityID == 1
select
and some use the explicity join syntax.
from h in db.Hubs
join ch in da.CityHubs on h.CityId equals ch.CityId
select
If I am using Linq to entities, which one should I use? If I were to use Linq to objects, which one should I use?
As a rule, in Entity Framework, if you have a proper model and properly set up navigation properties for foreign keys, you should almost never use join - instead you access your navigational property directly and EF will generate the necessary join in the SQL code for you. I recommend taking a look at #Craig Stuntz's blogpost regarding this issue.
Regarding Linq-to-objects, however, it depends on the particular query you are writing.

Resources