NHibernate: Require inner join instead of left join for References - nhibernate

How can I change the default join type to be an inner join instead of a left outer join for mappings when I use References?
For Example:
public class SomeClassMap : ClassMap<SomeClass>
{
public SomeClassMap()
{
Id(x => Id);
References(x => x.Account);
}
}
this usually turns out to be something like this...
FROM SomeClass SC
LEFT OUTER JOIN Account A
ON SC.Id = A.Id
I'd like to have this be an inner join instead of a left outer join. Any thoughts?

Similar question here:
Inner or Right Outer Join in Nhibernate and Fluent Nhibernate on Many to Many collection
I'm assuming this also applies to one to many relationships. Someone please chime in if this does not hold true anymore.

Related

How to make a LEFT JOIN on a one-sided relation between two tables in HQL?

The title is explicit, so here is the detail : I have two tables, A and B. B has a reference to A but the other way around is not true. In SQL it does not really change anything, but in HQL I can not figure out how to do :
A LEFT JOIN B ON condition
I tried :
A a LEFT JOIN B b JOIN b.A ba WITH a.id = ba.id
--> QuerySyntaxException: Path expected for join!
A a LEFT JOIN B b WITH a.id = b.A.id
--> QuerySyntaxException: Path expected for join!
I don't get the path exception as I always give an alias. I guess I'm doing something that doesn't make sense, or most probably it is because I need to do A a LEFT JOIN a.B, but I can't...(I tried B b RIGHT JOIN b.A. It works but of course the result is not what I need)
I also tried without the WITH clause because the condition is on the FK, but no more sucess.
If you have any ideas, please, I'm listening !
Thank you.
Firstly, to do such ad hoc joins you need at least Hibernate 5.1. JPA still doesn't support such kind of things.
Try to use this query
class A {
#Id
private Long pid;
}
class B {
#Id
private Long pid;
#OneToOne
#JoinColumn
private A refToA;
}
from A a left join B b on a.pid = b.refToA.pid

Using a scope in a Joins in AR

Didn't find an answer for this in previous questions..
I have a scope in a model A
A.activated
which does pretty complex queries and joins, but it works properly.
I want to join A to B table as a LEFT OUTER JOIN but only the rows in A that are in the scope
B.joins(:c).joins("LEFT OUTER JOIN a ON a.some_column = c.some_other_column") <--- how to add the scope?
So the answer is the fabulous #merge, don't leave home with it!
B.joins(:c).joins("LEFT OUTER JOIN a ON a.some_column = c.some_other_column").merge(A.activated)
Ta da!

I can't make a inner join between two tables in hibernate hql query

I am new with this. Please help me.
My inner join looks like this:
select p.idprodus, p.denumire, p.cantitate from Produs p inner join Furnizor f
on p.idfurn = f.idfurn
I want to make the inner join on the column idfurn, but I get these errors:
org.hibernate.QueryException: outer or full join must be followed by path expression select p.idprodus, p.denumire, p.cantitate from sakila.entity.Produs p inner join Furnizor f
on p.idfurn = f.idfurn
at org.hibernate.hql.classic.FromParser.token(FromParser.java:170)
at org.hibernate.hql.classic.ClauseParser.token(ClauseParser.java:86)
at org.hibernate.hql.classic.PreprocessingParser.token(PreprocessingParser.java:108)
at org.hibernate.hql.classic.ParserHelper.parse(ParserHelper.java:28)
at org.hibernate.hql.classic.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:216)
at org.hibernate.hql.classic.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:185)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:56)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:72)
at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:133)
at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:112)
at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1623)
In HQL, you use entities, not tables. And entities are linked together by associations (OneToOne, OneToMany, etc.) Joins can anly be done between associated entities.
For example, if you have a ManyToOne association between Product and Provider, the HQL query is:
select p from Product p inner join p.provider provider where ...
The on clause is unnecessary, because Hibernate knows from the mapping of the ManyToOne association that a Product is associated with its provider using the product.id_provider foreign key to the provider.id_provider primary key.
All of this is very well explained, with lots of examples, in the Hibernate documentation.
If an association (e.g. OneToMany mapping) does not exist and you need an inner join then use the old cross join notation.

Linq2NHibernate - Only Left Joins?

Really quick question..
Does Linq2NHibernate always create a left join to retrieve relationships? Is there a way that I can get an inner one instead?
Thank you in advance.
Filipe
As far as I know.
For any relationship that is not One-to-One, NHibernate makes the assumption that the relationship could have 0 to many results, thus uses a Left Join.
I don't know about Linq2NHibernate, but in NH3 using QueryOver API you can specify the join types.
For example, give a Product with a Category. If you wrote:
var result = Session.QueryOver<Product>()
.Fetch(x => x.Category).Eager
.List();
This will result in a left join, if you wanted to specify an inner join you could write the same query as:
var result = Session.QueryOver<Product>()
.JoinQueryOver(x => x.Category, JoinType.InnerJoin)
.List();
This will result in an Inner Join.
As far as I know you can't specify join types when using the LINQ provider (Query<T> in NH3)

Left Join on Many-to-One Mapping

I have a reference to call that may or may not be there. When I add the nullable option it still doing Inner Join when I want an Left Join (show the left even if the right is null). Is this possible in the NH map?
References(x => x.DefaultCategory, "CATEGORY_ID")
.Nullable();
The join type isn't specified in the mapping, but in the query.
IN HQL, use left join syntax as with SQL.
With Criteria, use:
.CreateAlias("categories", "c", JoinType.LeftOuterJoin)