Spring JdbcTemplate Set Time Interval Hour - spring

Hi Could you please help me with this?
jdbcTemplate.update("update training.link_validity set start_time=now() , end_time=(NOW() + INTERVAL ?) where id=1", new Object[] { 6 });
It's working fine in PgAdmin but throwing an error here.
Error :
Caused by: org.postgresql.util.PSQLException: Can't infer the SQL type to use for an instance of [Ljava.lang.Object;. Use setObject() with an explicit Types value to specify the type to use.
at org.postgresql.jdbc2.AbstractJdbc2Statement.setObject(AbstractJdbc2Statement.java:2142)

Your statement in your description doesn't match the one from the screenshot, but anyhow:
You can set (and play with) the explicit SQLTypes in the JDBCTemplate. So try this out (and drop the explicit array creation if you want)
jdbcTemplate.update("update training.link_validity set start_time=now() , end_time=(NOW() + INTERVAL ? HOUR) where id=1", "6" , java.sql.Types.VARCHAR);
(I suppose the interval ? parameter is a string literal, but if it is a number, just change the types accordingly)

Related

Hibernate Spatial PostGis PSQLException column is of type point but expression is of type bytea

In a Spring Boot project, Java8, with hibernate-spatial and PostgresDB 9.4
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-spatial</artifactId>
<version>5.2.10.Final</version>
</dependency>
application.properties
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.database-platform=org.hibernate.spatial.dialect.postgis.PostgisPG94Dialect
spring.jpa.properties.hibernate.dialect=org.hibernate.spatial.dialect.postgis.PostgisPG94Dialect
(I tried also PostgisPG9Dialect)
My Entity has a property
...
import com.vividsolutions.jts.geom.Point;
....
#Column(columnDefinition = "Point")
private Point cityLocation;
If I save with null value it's ok, but if I put a value
setCityLocation(new GeometryFactory().createPoint(new Coordinate(lng, lat));
I have:
PSQLException: ERROR: column "city_location" is of type point but expression is of type bytea You will need to rewrite or cast the expression.
In my db I can see the column definition as
type: point
column size: 2147483647
data type: 1111
num prec radix: 10
char octet length: 2147483647
I'M GOING CRAZY... Why It doesn't work?
UPDATE (It still don't work, I'm collecting new informations)
1) I'm thinking the problem could be the creation of the db.
In my application.properties I also have :
spring.jpa.properties.hibernate.hbm2ddl.auto=update
so the schema will update 'automatically' by hibernate.
2) I can run with success a query directly on the db (I use "Squirrel SQL" as client)
update my_table set city_location = POINT(-13,23) where id = 1
and if I
select city_location from my_table where id = 1
the answer is
<Other>
I can't see the value... I got the same answer for the record with null value inside the point type...
3) After set a value to the 'point' column with a query, I'm no more able to read from the table, I receive the exception:
org.geolatte.geom.codec.WktDecodeException : Wrong symbol at position: 1 in Wkt: (-13.0,23.0)
4) I look inside the hibernate-spatial-5.2.10.Final.jar and I found two "geolatte" named classes in the package org.hibernate.spatial :
GeolatteGeometryJavaTypeDescriptor.class
GeolatteGeometryType.class
5) And also (specific for Squirrel SQL client experts):
if I try to change a value of a column in "my_table" (not the 'point' city_location but anyone of the other columns) I recive an error similar to the one I recive in java when I try to insert a point value:
Exception seen during check on DB. Exception was:
ERROR: operator does not exist: point = character varying
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Squirrel is made with java.. so I can accept this strange thing, may be it compose the query in a 'wrong' way, maybe it is connected to the value I see when I make a select...
Any ideas?
I found the solution!!
A fix to the code was needed and a magic trick I read in another stackoverflow question saved my life.
The problem was that the db column was created in a wrong way:
in the db the column type should be geometry NOT point
I removed the columnDefinition = "Point" from the #Column annotation and I ran the query
CREATE EXTENSION postgis;
on my db following these instructions:
Postgis installation: type "geometry" does not exist
Krishna Sapkota you are my new super hero!
Just remove columnDefinition = "POINT", from #Column annotation, and just use the Point object. (i.e. Use default column definition)

IllegalArgumentException: Parameter with that position [1] did not exist -- LOWER & CONTAINING usage

I am new to Spring Data JPA. I have this Query. LOWER function and CONTAINING(case-insensitive) are mandatory.
It's working fine, if i use :
findByCityContainsAndAreaContainsAndType(String city,String area, String type);
The reason for using #Query is i wanted to use joins. But ('%?1%') seems to be having an issue.
Not sure how to implement it.
#Query(value=" select * from Agreement where LOWER(city) like LOWER('%?1%') and LOWER(AREA) like LOWER('%?2%') and type=?3", nativeQuery = true)
public List<Agreement> getAgreementDetailsByCityAreaAndType(String city,String area, String type);
Getting error:
Caused by: java.lang.IllegalArgumentException: Parameter with that position [1] did not exist
Also tried JPA:
#Query(value=" select sa from Agreement sa where LOWER(sa.city) like LOWER('%?1%') and LOWER(sa.area) like LOWER('%?2%') and sa.type=?3")
public List<Agreement> getAgreementDetailsByCityAreaAndType(String city,String area, String type);
Same issue:
Caused by: java.lang.IllegalArgumentException: Parameter with that position [1] did not exist
Also tried to use:
LOWER(city) like '%' + LOWER(?1) + '%'
from :
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#query-by-example.execution
But it's throwing query syntax errors at run time.
Any suggestions ?
Thanks
Ok, if you are using JPQL instead of native then i would suggest using the concat function:
#Query(value=" select sa from Agreement sa
where LOWER(sa.city) like LOWER(CONCAT('%', ?1, '%'))
and LOWER(sa.area) like LOWER(CONCAT('%', ?2, '%')) and sa.type=?3")
public List<Agreement> getAgreementDetailsByCityAreaAndType(String city,String area, String type);
I remember having some issues with the numbered parameters and had to use the named parameters. It was on an older version though so give it a try like above.

JOOQ - query without quotes

I use JOOQ-3.1.0 to generate and execute dynamic queries for Oracle and Postgresql with Spring-4. In a scenario I have a partitioned table, which I need to query using JOOQ. I use DSL.tableByName(vblTablename); where vblTablename is the string received as a string in the query generation method, ex, vbl_default partition(p_04-Dec-14). (The vblTablename pattern differs for different databases, and is configured in the external property file). The JOOQ generates the sql, but with the double-quote around the tablename. The query and error shown below
Query
SELECT COUNT(ID) COUNT FROM "vbl_default partition(p_04-Dec-14)"
where (rts between timestamp '2014-12-04 00:00:00.0' and timestamp '2014-12-05 00:00:00.0' and userid in (2))
Error
ORA-00972: identifier is too long
00972. 00000 - "identifier is too long"
*Cause: An identifier with more than 30 characters was specified.
*Action: Specify at most 30 characters.
Error at Line: 4 Column: 29
Though I have set the below settings on the DefaultDSLContext
Settings settings = new Settings();
settings.setRenderNameStyle(RenderNameStyle.AS_IS);
How do I remove the quote around the table? Any other settings have I missed?
The idea behind DSL.tableByName(String...) is that you provide a table ... by name :-)
What you're looking for is a plain SQL table, via DSL.table(String).
You can write:
// Assuming this import
import static org.jooq.impl.DSL.*;
DSL.using(configuration)
.select(count(VBL_DEFAULT.ID))
.from(table("vbl_default partition(p_04-Dec-14)"))
.where(...);
Or by using the convenient overload SelectFromStep.from(String)
DSL.using(configuration)
.select(count(VBL_DEFAULT.ID))
.from("vbl_default partition(p_04-Dec-14)")
.where(...);
More information about plain SQL in jOOQ can be obtained from this manual page:
http://www.jooq.org/doc/latest/manual/sql-building/plain-sql/
Partition support
Note that support for Oracle partitions is on the roadmap: #2775. If in the mean time you wish to use partitioned tables more often, you could also write your own function for that:
// Beware of the risk of SQL injection, though!
public <R extends Record> Table<R> partition(Table<R> table, String partition) {
return DSL.table("{0} partition(" + partition + ")", table);
}
... and then:
DSL.using(configuration)
.select(count(VBL_DEFAULT.ID))
.from(partition(VBL_DEFAULT, "p_04-Dec-14"))
.where(...);

Spring jdbcTemplate executing query

I have a strange problem ,
My Query looks like below.
String tokenQuery = "select id from table
where current_timestamp between
creation_time and (creation_time + interval '10' minute)
and token = '"+Token+"'";
But when I run, jdbcTemplate.queryForLong(tokenQuery) , no matter what , it always throws EmptyDataAccessException.
I am executing this in Oracle
Can we not append dynamic values to string and then pass it as a query and execute ?
What could be the issue ?
I assume that what you get is in fact an EmptyResultDataAccessException. The javadoc of this exception says:
Data access exception thrown when a result was expected to have at least one row (or element) but zero rows (or elements) were actually returned.
That simply means that the query is executed fine, and is supposed to return one row, but doesn't return any. So no row satisfies the criteria of your query.
If that is expected, then catch the exception, or use a method that returns a list rather then returning a single value. That way, you can test if the returned list is empty.
That said, you should use a parameterized query instead of concatenating the token like you're doing. This would prevent SQL injection attacks. It would also work even if the token contains a quote, for example.

How to handle missing rows in a dependent table

I have two Sql Server tables accessed through Entity Framework 4. They are joined by a single key with 0 to 1 rows on the dependent side of the join. Here is my linq query.
var typeDtoList = from type in typeList
select (new DxStudioTypeDto(parent,
isChildrenLoadOnDemand,
businessFacade,
server,
database,
type.typeGuid,
type.typeName,
type.writerName,
type.managerName,
type.Reporting_Type.MRef_Status,
type.Reporting_Type.Exists_In_Drop));
Obviously, if the Reporting_Type returns zero rows, the linq expression throws a null reference exception on the last two parameters of the DxStudioTypeDto constructor:
type.Reporting_Type.MRef_Status,
type.Reporting_Type.Exists_In_Drop));
Is there a way to detect the absence of a Reporting_Type row and substitute a default string? DxStudioTypeDto is an immutable type, so I need all the parameters available when I instanciate a new object. Any other strategies for this situation?
Did you try this?
((type.Reporting_Type == null) ? "some default value" : type.Reporting_Type.MRef_Status)
I know sometimes the EF engine returns a "the provider does not support this operation" for this kind of thing, but it's worth a try.

Resources