Save entity with java.time.Instant property using NamedParameterJdbcTemplate with postgres driver - postgresql

I am having issues saving my entity that has a Instant value using the NamedJdbcTemplate. I receive the exception listed below and I am trying to determine the best way to resolve this. Please advise.
Can't infer the SQL type to use for an instance of java.time.Instant. Use setObject() with an explicit Types value to specify the type to use.
I am using the postgresql:9.4.1212 driver

This code worked for me:
Instant ts = // whatever instant
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("ts", Timestamp.from(ts), Types.TIMESTAMP);
jdbcTemplate.queryForList(SQL, params)
where SQL is the parametrized query and make sure you're using java.sql.Timestamp and java.sql.Types.

Related

How to read data ignoring ValueConverters

I got a custom ValueConverter that serializes objects as JSON and stores them as a STRING in the database. This works well, but for some use cases I need to read the data as it is in the database, ignoring the ValueConverter. How to do that?
Unfortunatly, the API of a ValueConverter does not allow to disable a conversion, because my implementation has to return a value of type object and can't return a STRING.
I found this answer that is applicable to my problem. Use a projection and cast the property to its database type (STRINGin this example).
EmployeeSet.Select(e => new {Name = e.Name, RawData = (string)e.Data})

Update entity from expression (EF Core 2.0)

How can I update entity from expression?
I dynamically build which properties(columns) should be updated. Function that do that returns Expression<Func<T, T>> where T is entity.
I have loaded entity from database using Where and Single.
Expression<Func<T, T>> expr = this.CallVirtualMethodAndGetExpression(ModelFromRequest);
DbUser entity = this.context.Users.Where(t => t.Id == 1).Single();
some magic ??? //tried expr.Compile()(entity) but it does not work.
this.context.SaveChanges();
//use DbUser with updated properties of course.
I know I could use EF Plus (batch update), but I want to stick with SaveChanges (I need DbUser after SaveChanges and I want to avoid sending another request).
Updated:
I have entity object and expression. Now, I need to edit entity object based on expression and called SaveChanges which should update entity.
the magic line you are looking for:
var resultOfTypeT = expr.Compile().Invoke(entity)
But then entity needs to be an instance of type T , not DbUser
So this does not make sense to me.
So i cant give you exact code to compile for you, since i cant see the method signature where T is defined. and also do not know what the method signature of this.CallVirtualMethodAndGetExpression(ModelFromRequest) looks like.
But the Compile() will change the Expression<Func<T,T>> to just Func<T,T> which can then Invoke the defined functionality for Func<T,T> if you have a valid instance of T to pass to it.
Now your entity is not of type T, since it is of type DbUser So you are probably going to need to change your Method Signature or get your DbUser in a generic way or something. If you are only going to need to pass a DbUser instance, you do not need c# Generics. but cant really tell with just the current information available.

Entity Framework Core - FromSql error:

So I am attempting to use Entity Framework Core to call a stored proc and get some rows back into objects.
Following examples from the solution I was working in I had everything in place but it isn't working correctly to call the stored procedure or map the results back.
This was from a piece of code:
var list = this.context.DocumentList.FromSql<Document>("EXECUTE spSelDocsList #_iUserNumber", new { #_iUserNumber = UserId }).ToList();
Returning error:
"No mapping to a relational type can be found for the CLR type '<>f__AnonymousType23'."
After searching for this error more and trying to determine why it was returned I figured this out inadvertently.
From this stack overflow post:
No mapping exists from object type System.Collections.Generic.List when executing stored proc with parameters in EF 4.3
Turns out that passing an anonymous object for the SqlParameter will lead to this No Mapping to a relational type can be found for the CLR type '<>f__AnonymousType23'.
The fix for this to the code was simple, first put the parameter in an actual SqlParameter object. But passing that SqlParameter object wasn't working so by putting that in a List and returning that ToArray() IS accepted by the EF FromSql method.
List<SqlParameter> sqlParameters = new List<SqlParameter>();
sqlParameters.Add(new SqlParameter("#_iUserNumber", userId));
var list = context.DocumentList.FromSql<Document>("EXECUTE spSelDocsList #_iUserNumber", sqlParameters.ToArray()).ToList();

Automatically casting RHS values for specific JOOQ columns

I have the following code, where "CI_COL" is of type citext (https://www.postgresql.org/docs/current/static/citext.html)
String str = "testING";
int countBad = context.fetchCount(select(Tables.MY_TABLE.CI_COL)
.from(Tables.MY_TABLE)
.where(Tables.MY_TABLE.CI_COL.eq(str)));
int countGood = context.fetchCount(select(Tables.MY_TABLE.CI_COL)
.from(Tables.MY_TABLE)
.where(Tables.MY_TABLE.CI_COL.eq(cast(str, new DefaultDataType<>(SQLDialect.POSTGRES, String.class, "citext")))));
The first query returns 0, and the second query correctly returns > 0.
It took me a long time to track down the root cause, because when the first query was printed (or found in the DEBUG logging), it seemed to execute in the terminal just fine.
Once I got down to the statement level and actually started binding values, that's where the root cause seemed to be. It seems to be an issue (or on purpose) in the postgres driver. This post illustrates the binding issue with citext: https://www.postgresql.org/message-id/CAJFs0QB90bo0vWw5pZcw0c%3DLjOcOX04qPEM4nSd6uY7-T2r5hA%40mail.gmail.com
Is it possible to fix this at the JOOQ level, by having JOOQ automatically perform a cast on all right hand side values for a specific column?
Side note
new DefaultDataType<>(...)
Ghasp! You're using internal API :)
Correct solution
The correct way to introduce new data types in jOOQ is to use a Converter, or in this case a data type Binding:
http://www.jooq.org/doc/latest/manual/sql-building/queryparts/custom-bindings
While most Binding method implementations would simply delegate to jOOQ's DefaultBinding, you can override the sql() method (which generates the bind variable's SQL string) to this:
#Override
public void sql(BindingSQLContext<JsonElement> ctx) throws SQLException {
ctx.render().sql("?::citext");
}

Profiling DB2 connection with MiniProfier

I'm trying to add MiniProfiler to my DB2 connections. Below is my simplified code.
public void InitializeConnection()
{
DB2Connection cnn = new DB2Connection("connection String");
var profiler =
new StackExchange.Profiling.Data.ProfiledDbConnection(cnn, MiniProfiler.Current);
IDbCommand c = new DB2Command();
c.Connection = profiler ;
}
My problem is occurring in the last line where the profiler is assigned to the DB2Command's Connection property. I'm getting the below error.
Unable to cast object of type 'StackExchange.Profiling.Data.ProfiledDbConnection' to type 'IBM.Data.DB2.DB2Connection'
I've tried a couple of different casting ideas and nothing has worked out.
I think you're going at it backwards. You're assigning the connection to the ProfiledDbConnection class (as seems to be correct, based on the docs on the MiniProfiler website).
However, you're then creating a DB2-specific command object, and trying to assign the ProfiledDbConnection class to the connection object.
I think what you want to do is call profiler.CreateDbCommand(), which will create a ProfiledDbCommand object that uses the DB2Command class "under the covers".
The DB2Command.Connection property is of the type DB2Connection (as the error message helpfully tells you). Try DbConnection instead:
c.DbConnection = profiler
More in the manual