Oracle: date not valid for month specified in groovy - string

Using RestApi i am trying to fetch response and saving the data into database using groovy and java.
I have field Allocation Date where the format i am receiving from RestApi is for example
'"2020-06-30".
So in my java IData class i have created method as IN_DATE_FORMAT for input format:
public static final DateFormat IN_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
And in groovy class i have created constructor and using this method like below:
def contents = json.Contents as ArrayList
contents.parallelStream().each { rec ->
IData data = new IData ()
def allocDate = rec["Allocation Date"]
data.allocationDate = allocDate != null ? IData .IN_DATE_FORMAT.parse(allocDate as String) : null
When i am running the code i am getting in between few error as
ORA-01839: date not valid for month specified
And i am receiving corrupt date as for example '31-Apr-20' which is normally not correct as in April month we dont have date 31. And this value is not coming from RestApi. I dont understand from where this corrupt date value is coming from. Is it because of conversion and parsing the date into String ?
Can we use something like LocalDate in my code as this looks risky of parsing date into string ? And i think because of which its trying to store incorrect date value in database which even does not exist and received from RestApi.
Below are my logs for def allocDate = rec["Allocation Date"]:
WARNING: Failed to execute: insert into XXX (
ALLOCATIONDATE
) values (
'31-Apr-20'
)
because: ORA-01839: date not valid for month specified
10:57:16.103 [Actor Thread 3] WARN XXXX - Failed to execture record due to:ORA-01839: date not valid for month specified
Allocation Date:- 2020-06-30
Allocation Date:- 2020-06-25
Allocation Date:- 2020-07-30
Allocation Date:- 2020-05-30
Allocation Date:- 2020-06-25
....
Below is my Insert into DB method:
private boolean insertIntoDb(Map<String, List<IData>> ricMap) {
Sql conn = sql(ORACLE)
conn.withTransaction {
ricMap.entrySet().parallelStream().forEach { entry ->
entry.value.parallelStream().forEach { val ->
String values = """
${nullStr(val.allocationDate != null ? DbConnCfg.ORACLE_DATE_FORMAT.format(val.allocationDate) : null)}
"""
}
}
}
In DbConnCfg class i have defined ORACLE_DATE_FORMAT method as below:
public static final DateFormat ORACLE_DATE_FORMAT = new SimpleDateFormat("dd-MMM-yy");

You can parse a given date by using Date.parse(format, date). In your case, 31 April is parsed as May 1st. I don't know if this will solve your problem.
dt1 = '30-Apr-20'
dt2 = '31-Apr-20'
def format(dt) {
def newDt = new Date().parse("dd-MMM-yy", dt) //reverse-engineers the date, keeps it a Date object
return newDt.format("yyyy-MM-dd") //apply the format you wish
}
assert format(dt1) == '2020-04-30'
assert format(dt2) == '2020-05-01'

Related

date column which is a text type in Cassandra.so I need a UDF to convert that text to timestamp so I can query on that column

I have writeen code like belo but getting error as below:-
InvalidRequest:  Error from server:  code=2200 [Invalid query]  message="Java source compilation failed: Line 1: java.util.String cannot be resolved to a type  Line 1: Syntax error on token "Date", # expected  Line 4: SimpleDateFormat cannot be resolved to a type
CREATE FUNCTION saumya.text2dt ( input text )
RETURNS NULL ON NULL INPUT
RETURNS timestamp
LANGUAGE java
AS $$
java.text.ParseException
java.text.SimpleDateFormat
java.util.Date
String ms = input;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Date date = sdf.parse(ms);
return sdf.format(date);
$$
Create UDF syntax:
CREATE FUNCTION text2dt ( input text )
RETURNS NULL ON NULL INPUT
RETURNS timestamp
LANGUAGE java
AS '
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
try{
java.util.Date date = sdf.parse(input);
return date;
}catch(Exception e){
return null;
}
';

Unable to map values of a Set into a model

I have the following model
case class TagPartitionsInfo (
year:Int,
month:Int
)
case class TagPartitions(tag:String,
partition_info:Set[TagPartitionsInfo])
The data in the Cassandra table is stored like follows:
tag | partition_info
------------+--------------------------------------------------
javascript | {{year: 2018, month: 1}, {year: 2018, month: 2}}
When I am querying the table, I am trying to create the TagPartitions as follows from the ResultSet but my code isn't compiling. The issue seem to be the way I am extracting Set from the row:
TagPartitions(row.getString("tag"),row.getSet[TagPartitionsInfo]("partition_info",TagPartitionsInfo.getClass))
The error is Cannot resolve symbol getSet.
I also tried row.getSet("partition_info",TagPartitionsInfo.getClass) but then I see the error Type mismatch, expected Set[TagPartitionsInfo], actual util.Set[Any]
What am I doing wrong?
This worked. As I am using a UDT, I have to use UDTType and UDTValue to convert the UDT into my model
val tag = row.getString("tag")
val partitionInfoType:UserType = session.getCluster().getMetadata.getKeyspace("codingjedi").getUserType("tag_partitions")
//create value
//the logic below assumes that there is only one element in the set
val partitionsInfo =
row.getSet("partition_info",partitionInfoType.newValue().getClass)
println("tag is "+tag +" and partition info converted to UDTValue: "+partitionsInfo)
val udtValueScalaSet:Set[UDTValue] = partitionsInfo.asScala.toSet
//convert Set[UDTValue] = Set[TagPartitionsInfo]
val partitionInfoSet:Set[TagPartitionsInfo] = udtValueScalaSet.map(partition=>TagPartitionsInfo(partition.getLong("year"),partition.getLong("month")))
return TagPartitions(tag,partitionInfoSet)

compare and extract number from string in jpql

I have column named record_number of type varchar that has the following format data: [currentYear]-[Number] ex:2015-11
I need to search for the maximum number of this column; ie: if the value of the column that holds the maximum is 2015-15 and then the value should be 15, however if the column has a value of 2016-2, then the max should be 2.
how can I do it in jpql?
I'm using Postgres and EJB 3.1
You can use the SUBSTRING method of the JPA:
select table From Table table order by SUBSTRING(table.record_number, 5) desc;
To get only the first result, you need to use the method maxResults, like this:
em.createQuery("select table From Table table order by SUBSTRING(table.record_number, 5) desc")
.setMaxResults(1) -- only the first result
.getResultList()
I managed to fix the problem based on the comment of Dherik:
I used the following query to get the object that holds the correct value which seems more optimized than the one porposed by Dherik:
final TypedQuery<Table> query = createTypedQuery("from Table t where t.recordNumber= (select max(t.recordNumber) from t)", Table.class);
Table t= null;
try {
t = query.getSingleResult();
}catch(Exception e){
//handle Exception Here
}
return t;
The trick is since it's my app which creates the record number, I changed the method that creates the record number to format the number on 2 digits to avoid having wrong string comparaison (the case when '9' is considered greater than '10')
// format the number <10 so that is on 2 digits
final String formattedNumber = String.format("%02d", number);
final int year = SomeUtilClass.getYearFromDate(new Date());
return new StringBuilder().append(year).append("-").append(formattedNumber).toString();

Groovy String data to Date

How to convert String to Date ?
I tried this:
#RequestMapping("/data/{data}")
String buscar(#PathVariable String data, Model model) {
model.addAttribute 'dataBuscar', data
def newDate = data
def df1 = new SimpleDateFormat("dd/MM/yyyy 00:00:00")
data = df1.parse(newDate)
model.addAttribute 'acessos', acessoService.buscar(data)
'acesso/acesso.index'
}
but show me this message:
Unparseable date: "12-01-2014"
Why? Any idea ?
Your SimpleDateFormat pattern does not match the string you're trying to parse.
If you need to parse a string like "12-01-2014", you need:
new SimpleDateFormat("dd-MM-yyyy");
Tested Groovy script:
import java.text.SimpleDateFormat
def format = new SimpleDateFormat("dd-MM-yyyy")
def date = format.parse("14-01-2014")
println date // prints "Tue Jan 14 00:00:00 CST 2014"
As #tim_yates points out, Groovy provides the convenient method:
Date.parse('dd-MM-yyyy', "14-01-2014")

ServiceStack.OrmLite with a DateTime.Month Predicate

While using ServiceStack.OrmLite 3.9.70.0, and following some of the examples from the ServiceStack.OrmLite wiki.
I am trying to select rows where the LastActivity date month = 1.
I keep getting the error:
{"variable 'pp' of type 'Author' referenced from scope '', but it is not defined"}
LastActivity is a nullable DateTime, defind like:
public DateTime ? LastActivity { get; set;}
I have tried:
db.Select<Author>(q => q.LastActivity.Value.Month == 1);
AND
var visitor = db.CreateExpression<Author>();
db.Select<Author>(visitor.Where(q => q.LastActivity.Value.Month == 1));
AND
SqlExpressionVisitor<Author> ev = OrmLiteConfig.DialectProvider.ExpressionVisitor<Author>();
db.Select<Author>(ev.Where(q => q.LastActivity.Value.Month == 1));
AND
var predicate = ServiceStack.OrmLite.PredicateBuilder.True<Author>();
predicate = predicate.And(q => q.LastActivity.Value.Month == 1);
db.Select<Author>(predicate);
I am trying to avoid using a sql string in the select because I like the compile time checking of the field names and types.
do a less than and more than on the date field IE
LastActivity >= variableThatHoldsStartDateOfMonth && LastActivity <= VariableThatHoldsLastDayOfMOnth.
This will give you results for the whole month

Resources