Using database native functions in blaze persistence queries - spring-boot

CriteriaBuilder<Tuple> cb = cbf.create(em, Tuple.class);
cb.from(Pets.class);
cb.select("petId");
cb.orderByAsc("petId");
cb.where("petId").inExpression("select pet_id from get_authorized_pet_id(5)");
com.blazebit.persistence.PagedList<Tuple> rr =cb.page(1,10).getResultList();
The above query is trying to get all the Pets which are authorised for the account=5 user. get_authorized_pet_id is a native database query which does the checking and returns a list of pet_ids .
Blaze is not accepting this expressions . what am I missing here ?
The same thing is getting done through JPA Criteria though
criteriaBuilder.and(root.get(Pets_.PETS_ID)
.in(criteriaBuilder.function("SELECT pet_id from get_authorized_pet_id",
List.class,
criteriaBuilder.literal(getAuthorizedClient().getUser().getUserAccountId()));

Oh wow, this works almost by accident :D
There is no out of the box support for entity functions yet, but you could register a custom JPQLFunction (see https://persistence.blazebit.com/documentation/1.6/core/manual/en_US/#custom-jpql-functions) or even a Hibernate SQLFunction that renders this SQL fragment and then use the function name under which you register it e.g. .inExpression("get_authorized_pet_id(5)").

Related

Pagination feature in Pivotal GemFire

Is there any built-in API which provides a pagination feature in Pivotal GemFire, such as in the QueryService API or using Functions? We are currently using Pivotal GemFire 9.3.0 running in PCC.
TIA.
No yet. It is a planned feature for SD Lovelace/Moore release trains. See SGF-524 - Add support for PagingAndSortingRepositories. NOTE: sorting is already supported; paging is a WIP.
There is not. However there is a common pattern for this. Instead of directly querying the matching objects, write your query to return the keys of the matching objects. The client can then implement paging (e.g. page1 is key0-key99, page 2 is key 100-199, etc.). Use the "getAll" method with a list of keys to pull back one page at a time.
BTW, you can query the keys like this: "select key from /person.entries where value.ssn='222-22-2222'"

How to perform a NOT query with postgres_ext

Is it possible to perform a NOT type query with chained methods using postgres_ext?
rules = Rule.where.overlap(:tags => ["foo"])
Basically want the inverse of the above. Thanks!
In regular active record you can use .where.not as described in this article: https://robots.thoughtbot.com/activerecords-wherenot however looking through the source code of postgres_ext I don't know if it is defined in that library. You may be able to construct your query in a way that uses the native active record methods.

OData - converting parameter entity set to LINQ

I have an OData URI that works as I want, passing a value for a parameter called gridsize and retrieving the data from Results. This is the URI and it works fine:
http://<webservice>/MULTI_POINT_PARAMParameters(gridsize=0.1m)/Results
I am trying to get the above URI to work using LINQ. I am using an MVC service reference to generate the proxy class. So I tried this LINQ:
var query = (from x in context.MULTI_POINT_PARAMParameters
where
x.gridsize == 0.1M
select x);
However the above LINQ generates this URI, which fails saying "segement not found":
http://<webservice>/MULTI_POINT_PARAMParameters()?$filter=gridsize eq 0.1M}
What I really want LINQ to generate is this, which I know works:
http://<webservice>/MULTI_POINT_PARAMParameters(gridsize=0.1m)/Results
How can I get LINQ to generate the URI I want? I've looked at Linq2rest but could not see how it can help me if I want to explicitly code the LINQ terms myself, rather than have Linq2rest generate "hidden" terms I cannot see.
As far as my knowledge if you want to add filter in OData you have to use "$filter".
if you want to use "MULTI_POINT_PARAMParameters(gridsize=0.1m)" then you might have to use dynamic generation of LINQ.
After dynamic generation your query might look something like this
var query = (from x in context.MULTI_POINT_PARAMParameters(gridsize=0.1m)
select x);
I am just trying to give you a direction to think.Lets see what others have opinion on your question.

How to use SQL function in reference in NHibernate?

I'm using Fluent NHibernate on Oracle and my problem is I have to apply lower() function on every string in where conditions. I made my own dialect that instead Oracle lower function is being used nls_lower. Database is primarly used by Microsoft Dynamics AX and this function improve performance. In standard query like this everything works fine:
session.QueryOver<User>()
.Where(x => x.Name.lower() == userName.lower())
.SingleOrDefualt<User>();
But how can I apply this lower() function in references? I can't find anything suitable for this and I expect It can be done somehow. I would expect something like this in mapping class but I can't find it:
References<Settings>(x => x.Settings)
.Column("SettingId").lower();
I don't want to convert my string immediately to lowercase but I really need generate query like this:
select * from User where nls_lower(Name) == nls_lower("somename");
Thank you!
nls_lower is not a registered function in the Oracle dialect.
You can have a look in the code base in the Oracle8iDialect class.
In this situation you have to register your own extension. Have a look here.
When you've registered your dialect extension you should be able to call it this way:
var filter1 = Restrictions.Eq(
Projections.SqlFunction("nls_lower", NHibernateUtil.String,
Projections.Property<User>(x => x.Name)), userName.ToLower());
var user = session.QueryOver<User>();
user.Where(myFilter)
.SingleOrDefualt<User>();
You can define custom SQL to load entities. See here.

OrderBy("it." + sort) -- Hard coding in LINQ to Entity framework?

I have been trying to use dynamic LINQ to Entity in my application for specifying the OrderBy attribute at runtime. However when using the code as described in the majority of documentation:
var query = context.Customer.OrderBy("Name");
I received the following exception:
System.Data.EntitySqlException: 'Name' could not be resolved in the current scope or context. Make sure that all referenced variables are in scope, that required schemas are loaded, and that namespaces are referenced correctly.
After much searching I found this MSDN page:
http://msdn.microsoft.com/en-us/library/bb358828.aspx
Which included the following code example:
ObjectQuery<Product> productQuery2 = productQuery1.OrderBy("it.ProductID");
This prompted me to change my code to the following:
var query = context.Customer.OrderBy("it.Name");
After this the code works perfectly. Would anyone be able to confirm that this is indeed the correct way to get OrderBy working with LINQ to Entity? I can’t believe that the framework would have been implemented in this way, perhaps I have overlooked something?
Thanks, Matt
The it.Name syntax is ESQL and is indeed specific to the EF. There are good reasons to use this sometimes (e.g., collation specifiers), but it's not what I normally do.
Usually I use standard LINQ expressions:
var query = context.Customer.OrderBy(p => p.Name);
You can also use System.Linq.Dynamic, if you download it from Code Gallery, and then your original query:
var query = context.Customer.OrderBy("Name");
...will work.
No nice way, so far
My answer to this question was to create a stored procedure which has parameter to control sorting.

Resources