NHibernate.Linq -> The method CompareTo is not implemented - linq-to-nhibernate

Here's the problem: in short I use comb.guid identity strategy and I need all the rows made after the saved marker..
Here's dummy code example of what I am trying to get:
return session.Linq
.Where(p => p.Id.CompareTo(lastSyncedEntityIdentity)
== 1 )
.ToList();
This throws an exception saying that CompareTo is not implemented...
System.NotImplementedException occurred
Message=The method CompareTo is not implemented.
Source=NHibernate.Linq
StackTrace:
at NHibernate.Linq.Visitors.RootVisitor.VisitMethodCall(MethodCallExpression expr) in e:\horn\.horn\orm\nhcontrib\nhibernate.linq\Working-2.1\src\NHibernate.Linq\Visitors\RootVisitor.cs:line 97
InnerException:
As you can see from stack I have tried the 2.1 version from hornget trunk without any help
Any hint/clue what I have to do in order to go around this limitation which I guess is impacting most of folks using comb.guid strategy?
Thanks,
Nikola

The issue here is that the method CompareTo cannot be translated into an SQL query.
Remember that all NHibernate.Linq is doing is building an SQL Select statement from the predicate defined in a lambda expression, anything used in the lambda must be translatable to a comparable SQL statement.
so
session.Linq.Where(p => p.Id == 10299);
can be translated to
SELECT * FROM Table WHERE Table.Id = 10299
however there is no SQL command for CompareTo as this is a .net method.

Related

How can I call this jOOQ generated function taking a custom bound type?

I originally had the following SQL function:
CREATE FUNCTION resolve_device(query JSONB) RETURNS JSONB...
and the following code calling the method generated by jOOQ:
final JsonArray jsonArray = jooqDWH.select(resolveDevice(queryJson)).fetchOne().value1().getAsJsonArray();
final JsonObject o = jsonArray.get(0).getAsJsonObject();
This worked fine. I needed to return a real device object rather than a JSON blob though, so I changed the SQL function to:
CREATE FUNCTION resolve_device(query JSONB) RETURNS SETOF device...
and the code to:
final ResolveDeviceRecord deviceRecord = jooqDWH.fetchOne(resolveDevice(queryJson));
but I am getting a runtime error:
org.jooq.exception.SQLDialectNotSupportedException: Type class com.google.gson.JsonElement is not supported in dialect DEFAULT
Many other parts of my code continue to work fine with the custom binding I have converting JsonElement to JSONB, but something about the change to this function's signature caused it to stop working.
I tried a few different variants of DSL.field() and DSL.val() to try to force it to be recognized but have not had any luck so far.
This could be a bug in jOOQ or a misconfiguration in your code generator. I'll update my answer once it is clear what went wrong.
Workaround:
Meanwhile, here's a workaround using plain SQL:
// Manually create a data type from your custom JSONB binding first:
final DataType<JsonObject> jsonb = SQLDataType.OTHER.asConvertedDataType(jsonBinding);
// Then, create an explicit bind variable using that data type:
final ResolveDeviceRecord deviceRecord =
jooqDWH.fetchOptional(table("resolve_device({0})", val(queryJson, jsonb)))
.map(r -> r.into(ResolveDeviceRecord.class))
.orElse(null);

Jira groovy script error

I'm getting groovy records from SQL Table or Function. Example;
String subeKodu = get_sube_kodu_bul(matcher[0][1])
private String get_sube_kodu_bul(String subeAdi) {
def sql = Sql.newInstance("jdbc:jtds:sqlserver://10.xx.xx.xx:1433/DBNAME", "usrname","pass", "net.sourceforge.jtds.jdbc.Driver")
subeAdi = subeAdi.trim()
def row = sql.firstRow("SELECT TOP 1 SUBE_KODU FROM TABLENAME WHERE SUBE_ADI= '${subeAdi}'")
row != null ? (String)row.SUBE_KODU : ''
}
But I am faced with the following error;
WARNING: In Groovy SQL please do not use quotes around dynamic expressions (which start with $) as this means we cannot use a JDBC PreparedStatement and so is a security hole. Groovy has worked around your mistake but the security hole is still there. The expression so far is: SELECT TOP 1 YETKILI FROM TABLENAME WHERE SUBE_ADI = '?'
Groovy is complaining that your code may be vulnerable to a SQL injection attack.
The proper way to do this is with JDBC Prepared Statements. In Groovy, you do this as follows:
sql.firstRow("SELECT TOP 1 SUBE_KODU FROM TABLENAME WHERE SUBE_ADI= ?", [subeAdi])
For more examples of this, see the Groovy SQL tutorial and search for "prepared statements".
Also, don't forget to call close() when you are done.

Astyanax parepared statement withvalues() not working properly

today I migrated to Astyanax 1.56.42 and discovered, that withValues() on prepared statements doesn't seem to work properly with SQL SELECT...WHERE...IN ().
ArrayList<ByteBuffer> uids = new ArrayList<ByteBuffer>(fileUids.size());
for (int i = 0; i < fileUids.size(); i++) {
uids.add(ByteBuffer.wrap(UUIDtoByteArray(fileUids.get(i)), 0, 16));
}
result = KEYSPACE.prepareQuery(CF_FILESYSTEM)
.withCql("SELECT * from files where file_uid in (?);")
.asPreparedStatement()
.withValues(uids)
.execute();
If my ArrayList contains more than one entry, this results in error
SEVERE: com.netflix.astyanax.connectionpool.exceptions.BadRequestException: BadRequestException: [host=hostname(hostname):9160, latency=5(5), attempts=1]InvalidRequestException(why:there were 1 markers(?) in CQL but 2 bound variables)
What am I doing wrong? Is there any other way to handle a SQL SELECT...WHERE...IN () - statement or did I find a bug?
Best regards
Chris
As you mentioned because you are supplying a collection (ArrayList) to a single ? Astyanax throws an exception. I think you need to add a ? for each element you want to have inside the IN clause.
Say you want to have 2 ints stored in an ArrayList called arrayListObj the where clause, your statement looks like this:
SELECT & FROM users WHERE somevalue IN (arrayListObj);
Because you are suppling a collection, this cant work, so you will need multiple ?'s. I.e. you want :
SELECT name, occupation FROM users WHERE userid IN (arrayListObj.get(0), arrayListObj.get(1));
I couldn't find anything on the Astyanax wiki about using the IN clause with prepared statements.

nDepend querying direct indirect methods for all methods in an assembly

I am trying to retrieve all direct indirect method calls for all methods in an assembly using the CQL provided by nDepend.
Issue is I am not able to iterate through all methods inside a assembly to get this info.
The DepthOfIsUsedBy only allows a string type and not a collection of strings.
Is there a way t get this info for all methods inside an assembly?
What about using the method DepthOfIsUsing() instead of DepthOfIsUsedBy() :o)
from m in Assemblies.WithNameNotIn("nunit.uikit").ChildMethods()
let depth0 = m.DepthOfIsUsing("nunit.uikit")
where depth0 >= 0 orderby depth0
select new { m, depth0 }
This query has been generated through the menu below. (Btw a more sophisticated solution could be elaborated with the magic method FillIterative(), but it is not necessary here).
Taking account the comment of Prasad, what about trying this query that list all direct & indirect callers from A, for each method of B:
from m in Assemblies.WithNameIn("AsmB").ChildMethods()
where m.IsPubliclyVisible // Optimization
let indirectcallers = m.MethodsCallingMe
.FillIterative(
callers => callers.SelectMany(m1 => m1.MethodsCallingMe))
.DefinitionDomain
.Where(m1 => m1.ParentAssembly.Name == "AsmA")
.ToArray() // Avoid double enumeration
where indirectcallers.Length > 0
orderby indirectcallers.Length descending
select new { m, indirectcallers }

Complex queries in linq to nhibernate

We are using accountability pattern for organizational structure. I using linq to nhibernate to find some departments and position but I have two problem.
var query =
Repository<Party>.Find(p => p.IsInternal == true)
.Where(p => p.Parents.Any(c => c.Parent.PartyId == id))
.Where(p =>
(
p.PartyType.PartyTypeId == (int)PartyTypeDbId.Department &&
_secretariat.Departments.Select(c => c.PartyId).Contains(p.PartyId)
)
||
(
p.PartyType.PartyTypeId == (int)PartyTypeDbId.Position &&
p.Children.Any(c =>
c.AccountabilityType.AccountabilityTypeId == (int)AccountabilityTypeDbId.TenurePersonOfPosition &&
((Person)c.Child).UserName != null)
)
);
First : I got 'Unhandled Expression Type: 1003' for this part of query : '_secretariat.Departments.Select(c => c.PartyId).Contains(p.PartyId)'
and I got Property not found 'UserName'
We have many complex queries i think we need to use stored procedure.
Sorry for bad Inglish!
One nice thing that you can do with LINQ is break your queries into multiple parts. Since you are building an expression tree that won't get executed until the results are enumerated, you don't have to do it all in one line (like SQL).
You can even make some reusable "filters" that you can apply to IQueryable. These filter functions accept an IQueryable as an argument, and return one as a result. You can build these as extension methods if you like (I like to).
As for your immediate problem, you may want to try a join on _secretariat instead of attempting a subquery. I've seen them work in scenarios where subqueries don't.
In addition to Lance's comments you might want to look at a compiled Linq query and breaking up some of the responsibilties to follow SOLID principles.
I've just also found out that there are issues with the Contains when containing Any linq methods. However, Any seems to work well within Any, hence:
_secretariat.Departments.Select(c => c.PartyId).Any(x => x == p.PartyId)

Resources