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

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));

Related

Run complex SQL Query with spring boot repositories

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

FetchTypes in Spring Data JPQL Query (MultipleBagFetchException)

I am using Spring Data and defining following query:
#Query("SELECT u FROM AppUser u LEFT OUTER JOIN fetch u.userRights a LEFT OUTER JOIN fetch u.userGroups g LEFT OUTER JOIN fetch u.userGroups ug LEFT OUTER JOIN FETCH ug.groupRights where u.login = :login")
public Optional<AppUser> findOneWithCompleteRights(#Param("login") String login);
As you might see, I want to get back the logged in user with all his access rights. While starting the spring application, it runs into:
Caused by: javax.persistence.PersistenceException: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
I have checked following:
Multiple fetches with EAGER type in Hibernate with JPA
If I change all#XXXToMany Types to java.util.Set, it works, but I would like to decide the type on my own...
The other annotations of linked solution (see bottom) seem to be ignored if attached to the #Query method. Second would not make sense, anyway.
Load each collection separately using subselect #Fetch(FetchMode.SELECT)
Force usage of list instead of bag by adding index column #IndexColumn(name="LIST_INDEX")
Does anybody have another solution rather than setting the type to Set?
I had that problem also.
It happens when the class to load has more than on property of type List mapped.
You can resolve that,
by changing the type of
AppUser.userRights and AppUser.userGroups
from java.util.List to java.util.Set.
Not using Set here instead of List is exactly what Vlad Mihalcea is describing in this post and in some answers on StackOverflow. In his post he says to use separate queries.
But he is giving the solution not with the #Query-Annotation provided by the Spring-Data Project rather using JPQL-statements and the entityManager.
So to achieve the separate Query-Execution I would have thought, that the #Fetch(FetchMode.SELECT) (or SUBSELECT, not yet sure about the difference) would be a proper solution. But not for the #Query-Annotation but for the attribute in the class.
So in your case maybe:
class AppUser {
....
#OneToMany
#Fetch(FetchMode.SELECT)
List<UserRights> userRights
....
}
But trying that in my own project did not work, either. So another solution might be to somehow create multiple queries in the Statement of the #Query-Annotation, to act according Vlad's suggestion Not sure if that is possible in the Annotation-Parameter itself or if there has to be two Methods with two annotations.
#Query(
"SELECT u FROM AppUser u
LEFT OUTER JOIN fetch u.userRights a
LEFT OUTER JOIN fetch u.userGroups g
LEFT OUTER JOIN fetch u.userGroups ug
LEFT OUTER JOIN FETCH ug.groupRights where u.login = :login"
)
public Optional<AppUser> findOneWithCompleteRights(#Param("login") String login);

OBIEE 10G outer join

I am new to OBIEE 10G.
I have a DimA (dimension), FactA (fact). I mapped foreign key relationship between DimA and FactA on DimA.A = FactA.A in BMM, the relationship is inner and greyed out, so I can't change it to outer join.
So in the answers report, it only shows data of the inner join of the two tables. What I want is to show all items in DimA and related items of FactA or 0 for those not related.
I have posted a similar question here before https://forums.oracle.com/thread/2596618
But I still can't modify the relationship (still greyed out) even if I opened a offline repository.
And what I am thinking is is there an option in answers to dynamically control the join (inner or outer). For example, sometimes I want to show only matched DimA and FactA , sometimes all DimA and related FactA or 0, so that I don't have to modify the BMM in repository every time if the requirement changes.
What's the best practice for this case?
Thanks.
--update
I found in physical diagram, I can't change the type of relationship (complex join or foreign key). But in logical diagram I can change for both.
I found these useful:
http://everythingoracle.com/obieeldd.htm
http://obinsight.blogspot.co.uk/2010/05/understanding-complex-join-and-physical.html
If you're in OBIEE 10g, you can use a complex join. in a complex join, you can modify the join type.

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.

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