I would like to ask if there is any possibility to use object aggregation functions in JPA (which uses HQL). Functions like json_agg()
I would like to achieve something like. So the goal is to take entity and transform it into string.
Expressions.stringTemplate("jsonb_agg(json_build_object('entity', {0}))", qEntity.id)
Why I try to do I am getting org.hibernate.QueryException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode error. I´ve read that problem is I can not use HQL cause I can not use the HQL object properties in json aggregation functions.
I would like to avoid using querydsl-sql as much as I can (It makes complications in docker app deployment, It needs to be connected to database etc). So is there any way how to agregate objects like this using HQL? I am using spring-data-jpa so these is opportunity to use this tool to if there is better solution in it.
Your QueryDSL snippet looks just fine, but you need to register custom functions for JSONB_AGG and JSON_BUILD_OBJECT as well as custom types for the JSONB result.
For the custom JSONB type you can use the JsonBinaryType from the hibernate-types library.
For the custom function, you need to create a MetadataBuilderInitializer that registers the SQL functions with Hibernate. you can take inspiration from my hibernate-types-querydsl-apt library (for example ArrayFunctionInitializer). Applied to JSON functions specifically, you would end up with something along the lines of:
public class ArrayFunctionInitializer implements MetadataBuilderInitializer {
#Override
public void contribute(MetadataBuilder metadataBuilder, StandardServiceRegistry standardServiceRegistry) {
metadataBuilder.applySqlFunction("json_build_object", new StandardSQLFunction("json_build_object", JsonBinaryType.INSTANCE));
metadataBuilder.applySqlFunction("jsonb_agg", new StandardSQLFunction("jsonb_agg", JsonBinaryType.INSTANCE));
}
}
Related
I'd like to be able to implement a search method that can take any arbitrary properties of my POCO class as arguments. This works well:
public static IEnumerable<iUser> Search(DataContext context, Func<iUser, bool> predicate)
{
return from i in context.GetTable<iUser>().Where(predicate) select i;
}
but in this case the filtering appears to take place after collecting all the rows in the table.
Is it possible to use Linq to generate an arbitrary query like this without filtering after the sql call? What approaches would you recommend?
Thanks!
LINQ to DB is an Object-Relational Mapper (ORM) that is capable of translating LINQ expressions into SQL. The word "expression" is important here. A Func is not an expression but a delegate, you have to use Expression<Func<>> in LINQ methods for LINQ to DB to be able to translate them. Otherwise the data will be pulled from the database first after which the Func filters them in memory.
So your function should look like:
public static IEnumerable<iUser> Search(DataContext context,
Expression<Func<iUser, bool>> predicate)
{
return context.GetTable<iUser>().Where(predicate);
}
The return type depends on the what you want the caller of this function to be capable of. If you return IQueryable<iUser> the caller will be able to extend the expression by their own expressions. That is, Search(context, somePredicate).Where(...) will be translated into SQL as a whole. Returning IEnumerable will apply any subsequent predicates (either as Func or as Expression) in memory.
Side note, in order to line up with common naming conventions, if iUser is an interface (I have no idea if LINQ to DB supports interfaces) then you should rename it into IUser, otherwise name it User.
Looking to achieve the below but it is failing as the locations.Any() is being treated as an IEnumerable instead of an IQueryable and scalar functions invoked via EF require IQueryable. I need this filter to happen at the database level (not materialize the list first).
How can I get the locations.Any() to be treated as an IQueryable here? I understand the list doesn't exist in the database but is there a way for Entity Framework to understand this any and build and AND statement with nested OR in SQL?
public Address GetAddresses(List<Loctions> locations)
{
_context.Addresses.
Where(a => locations.Any(l => MyContext.CustomFunction(l.PropA,l.PropB, a.PropA, a.ProbB) > 1 ))
}
[DbFunction("fn_DistanceBetweenCoordinates", "dbo")]
public static decimal CustomFunction(decimal SourceLatitude, decimal SourceLongitude, decimal TargetLatitude, decimal TargetLongitude) {
throw new NotImplementedException();
}
You could achieve this by moving CustomFunction into the database and use that server side function when querying from EF.
Please read User defined function mapping and try to adapt the sample according to your use case.
We haven't seen the body of the CustomFunction, so it's impossible to tell if it's viable to do the transfer from client based UDF to server based.
We also don't know how the Locations list is populated. Depending on how that is done, the adaptation of the example code might become more cumbersome.
I am aware that extension functions are used in Kotlin to extend the functionality of a class (for example, one from a library or API).
However, is there any advantage, in terms of code readability/structure, by using extension functions:
class Foo { ... }
fun Foo.bar() {
// Some stuff
}
As opposed to member functions:
class Foo {
...
fun bar() {
// Some stuff
}
}
?
Is there a recommended practice?
When to use member functions
You should use member functions if all of the following apply:
The code is written originally in Kotlin
You can modify the code
The method makes sense to be able to use from any other code
When to use extension functions
You should use extension functions if any of the following apply:
The code was originally written in Java and you want to add methods written in Kotlin
You cannot change the original code
You want a special function that only makes sense for a particular part of the code
Why?
Generally, member functions are easier to find than extension functions, as they are guaranteed to be in the class they are a member of (or a super class/interface).
They also do not need to be imported into all of the code that uses them.
From my point of view, there are two compelling reasons to use extension functions:
To "extend" the behaviour of a class you're not the author of / can't change (and where inheritance doesn't make sense or isn't possible).
To provide a scope for particular functionality. For example, an extension function may be declared as a freestanding function, in which case it's usable everywhere. Or you may choose to declare it as a (private) member function of another class, in which case it's only usable from inside that class.
It sounds like #1 isn't a concern in your case, so it's really more down to #2.
Extension functions are similar to those you create as a utility functions.
A basic example would be something like this:
// Strings.kt
fun String.isEmail() : Boolean {
// check for email pattern and return true/false
}
This code can be written as a utility function in Java like this:
class StringUtils {
public static boolean isEmail(String email) {
// check for email pattern and return true/false
}
}
So what it essentially does is, calling the same function with the object you call on will be passed as the first parameter to the argument. Like the same function I have given example of in Java.
If you want to call the extension function created in kotlin from java, you need to pass the caller as the first argument. Like,
StringsKt.isEmail("example#example.com")
As per the documentation,
Extensions do not actually modify classes they extend. By defining an extension, you do not insert new members into a class, but merely make new functions callable with the dot-notation on variables of this type.
They are simply static functions with the caller as the first argument and other parameters followed by it. It just extends the ability for us to write it that way.
When to create extension functions?
When you don't have access to that class. When that class belongs to some library you have not created.
For primitive types. Int, Float, String, etc.
The another reason for using extension function is, you don't have to extend that class in order to use the methods, as if they belong to that class (but not actually part of that class).
Hope it makes a bit clear for you..
As mentioned in other answers, extension functions are primarily used in code that you can't change - maybe you want to change complex expression around some library object into easier and more readable expression.
My take would be to use extension functions for data classes. My reasoning is purely philosophical, data classes should be used only as data carriers, they shouldn't carry state and by themselves shouldn't do anything. That's why I think you should use extension function in case you need to write a function around data class.
Just about to start playing with jOOQ for a proof of concept. jOOQ looks really simple, expressive and makes SQL maintenance a lot more easier.
We're a Java 8 shop. The usecase here is to write the data layer for a reporting app that dynamically queries tables, columns, filters and functions based on the user selection on the screen.
Although I really like the idea of writing type-safe queries (using the jOOQ codegen), I suppose for my usecase, that won't be a best fit. Because tables, columns etc etc are completely unknown, I suppose I just need the jOOQ SQL builder. That means I have to give up type safety. Is my assessment correct? Or are there any patterns I could use for building "dynamic" SQLs without compromising the type safety? Any pointers would be much appreciated.
You don't have to use jOOQ's code generator to take advantage of most features in jOOQ. The manual's introduction section states that jOOQ can be easily used as a SQL builder without the extra type static safety provided by the code generator:
https://www.jooq.org/doc/latest/manual/getting-started/use-cases/jooq-as-a-standalone-sql-builder
The type safety provided by code generation
The code generator essentially provides two type safety elements:
Names of objects are hard-wired into class names (tables, schemas, sequences, data types, procedures, etc.) and attribute names (columns, type attributes, procedure parameters).
Types of attributes (columns, attributes, parameters) are hard-wired into the generic attribute definitions.
These things certainly helps develop your application
The type safety provided by the jOOQ API
... but beware that the code generator simply reverse engineers a static snapshot of your schema. It is type safe because the entire jOOQ API allows for this kind of type safety. For instance, a Field<T> type has a generic type <T>, which can be used without the code generator as well, e.g. by using the plain SQL APIs:
Field<String> firstName = field(name("USER", "FIRST_NAME"), SQLDataType.VARCHAR(50));
The above API usage (DSL.field(Name, DataType)) does roughly the same as what the code generator would do anyway. It creates a column reference with column type information attached to it. You can use it like the columns generated by the code generator:
DSL.using(configuration)
.select(firstName)
.from(name("USER"))
.where(firstName.like("A%")) // Compiles
.and(firstName.eq(1)) // Doesn't compile: firstName must be compared to String
.join(name("ADDRESS")) // Doesn't compile: the SQL syntax is wrong
.fetch();
As you can see, the only thing that changed compared to using the code generator is the table / column references.
Dynamic SQL
But this means, that jOOQ is even more powerful for you without the code generator. You can still create dynamic SQL statements very easily. For instance:
// Construct your SQL query elements dynamically, and type safely
Condition condition = hasFirstNameFilter()
? firstName.like("A%")
: DSL.trueCondition();
DSL.using(configuration)
.select(firstName)
.from(name("USER"))
.where(condition) // Use dynamically constructed element here
.fetch();
You could also do this in a "functional way":
DSL.using(configuration)
.select(firstName)
.from(name("USER"))
.where(condition()) // Call a function to create the condition here
.fetch();
Or even better
public static Select<Record1<String>> firstNames(
Function<? super Field<String>, ? extends Condition> condition
) {
return
DSL.using(configuration)
.select(firstName)
.from(name("USER"))
.where(condition.apply(firstName)); // Lazy evaluate the predicate here
}
// Use it like this:
firstNames(col -> col.like("A%")).fetch();
Or even better, make the above a higher order function:
public static Function<
? super Function<? super Field<String>, ? extends Condition>,
? extends Select<Record1<String>>
> firstNames() {
// Lazy construct query here
return f -> DSL.using(configuration)
.select(firstName)
.from(name("USER"))
.where(f.apply(firstName)); // Lazy evaluate the predicate here
}
// Use it like this:
firstNames().apply(col -> col.like("A%")).fetch();
More details here:
https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql
Conclusion:
As you can see, while the code generator does add a lot of value for static schemas, there's nothing really static in the jOOQ API. jOOQ is an API for dynamic SQL query construction, that just happens to work well for static queries as well.
I'd like to implement a method which allows me to access a property of an unknown/anonymous object (-graph) in a late-bound / dynamic way (I don't even know how to correctly call it).
Here's an example of what I'd like to achieve:
// setup an anonymous object
var a = new { B = new { C = new { I = 33 } } };
// now get the value of a.B.C.I in a late-bound way
var i = Get(a, "B.C.I");
And here's a simple implementation using "classic" reflection:
public static object Get(object obj, string expression)
{
foreach (var name in expression.Split('.'))
{
var property = obj.GetType().GetProperty(name);
obj = property.GetValue(obj, null);
}
return obj;
}
What other options do I have with C# / .NET 4 to implement something similar as shown above, but maybe simpler, more performant, etc.?
Maybe there are ways to achieve the same thing, which would allow me to specify expression using a lambda expression instead of a string? Would expression trees be helpful in any way (e.g. as shown in this question)?
Update: the object and the expression are passed into my code via a web service call. That's why I used object and string in my Get() method.
Do you actually only have the expression as a string? Is it known at compile-time, just that the types themselves aren't known (or are hard to express)? If so:
dynamic d = a;
int i = d.B.C.I;
If you really only have it as a string (e.g. as user-entered data) that makes life a lot harder, and none of the C# 4 features really help you. You could potentially evaluate it as an IronPython script or something like that...
EDIT: Okay, after the update it sounds like you're in the latter situation - in which case, I don't know of a nicer way than using reflection. Some of the built-in property binding built for UIs may help, but I don't know of a clean way of accessing it.
If you want to use C# style, you could use the Mono compiler as a service from your application. I describe how to do this here:
Mono Compiler as a Service (MCS)
As an alternative approach, you could use reflection to put all of your object's properties into an ExpandoObject then use it like a dictionary (because ExpandoObject implements IDictionary). Alternatively, you could use JSON.NET and call JObject.FromObject, which will turn a regular object into a JObject which is accessible in a dictionary-like style (and as an added benefit has recursive graph support). Lastly, you could use the same approach to dump your object into a dictionary of dictionaries.