(JAVA) Need to convert DATE to prepared statement for SQL - java

I have been looking and trying solutions provided on the web (and SO) for the last hour on how to use the Date type in Java but I can't seem to get it working. I am using NetBeans 11.2 and I am not used to Java and it is giving me a hard time (no pun intended). It seems that LocalDateTime, Date and Time are deprecated and that I should be using java.time.
To be honest, I don't know what to do anymore. I am trying to build a query with inputs value to save in mySQL database.
The source of the Date is from <input type="date">
SignIn.java (servlet) :
String birthDate = request.getParameter("data_birthdate");
UserDto userDto = null;
UserDao userDao = new UserDao();
try
{
// Tried this
userDto = userDao.CreateUser(LocalDateTime.parse(birthDate));
// Tried that
userDto = userDao.CreateUser(Date.parse(birthDate));
// Tried this
userDto = userDao.CreateUser(Time.parse(birthDate));
}
userDao.java (Dao) :
public void CreateUser(Date dateBirth) throws SQLException {
try {
connect = db.getConnect();
ps = connect.prepareStatement(SQL_CreateUser);
ps.setDate(1, dateBirth);
ps.executeUpdate();
}
}

You may use LocalDateTime along with PreparedStatement#setTimestamp(). Here is roughly how you would do that:
String birthDate = request.getParameter("data_birthdate");
// assuming your text birthdates look like 1980-12-30 00:30:05
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime dt = LocalDateTime.parse(birthDate, formatter);
try {
connect = db.getConnect();
ps = connect.prepareStatement(SQL_CreateUser);
ps.setTimestamp(3, Timestamp.valueOf(dt));
}
catch (Exception e) {
// handle exception
}
Note carefully the format mask being used in the call to DateTimeFormatter#ofPattern. You need to replace that with whatever mask actually fits your string dates.

Related

Why can't H2 database parse a timestamp?

My project is using Oracle database, and everything works just fine. For the purpose of testing I set up an H2 db. The following query now throws an error:
"SELECT * FROM ERESIS.ECH_HISFAB f WHERE f.FG_ETAT = 'A' AND TO_DATE(DT_INS) > '30-AUG-18' ORDER BY f.CD_MAT"
error:
Cannot parse "TIMESTAMP" constant "30-AUG-18"; SQL statement:
I can fix the error by setting up the string like TO_DATE('30-AUG-2018'), but changing the query kind of defeats the purpose since I already am sure the query works (but I need it to test the service). Is there any way to bypass this error without changing the query?
parsedatetime() should be able to convert string to TIMESTAMP, please try using -
"SELECT * FROM ERESIS.ECH_HISFAB f WHERE f.FG_ETAT = 'A' AND TO_DATE(DT_INS) > parsedatetime('30-AUG-2018', 'dd-MMM-yyyy') ORDER BY f.CD_MAT"
I had a similar issue with H2 (1.4.200), it has just one format for TO_DATE(input) method "DD MON YYYY".
After a debug I found that H2 uses an enum for date format when it's not provided as second parameter: org.h2.expression.function.ToDateParser.ConfigParam
TO_DATE("DD MON YYYY")
I did a solution to override it using reflection so that the sql code does not change.
In my unit test I created a utility method used to instantiate the workaround on #BeforeClass
private static boolean h2WorkaroundApplied = false; //utility to apply workaround just one time
protected static synchronized void applyH2ToOracleCompatibilityWorkaround() {
if (!h2WorkaroundApplied) {
fixH2ToDateFormat(); //apply to_date workaround
h2WorkaroundApplied = true; //disable future changes of same workaround
}
}
private static void fixH2ToDateFormat() {
try {
Class<?> classConfigParam = Arrays.stream(ToDateParser.class.getDeclaredClasses())
.filter(c -> "ConfigParam".equals(c.getSimpleName()))
.findFirst()
.orElseThrow(); //get the enum inner class
Object toDateEnumConstant = Arrays.stream(classConfigParam.getEnumConstants())
.filter(e -> "TO_DATE".equals(((Enum) e).name()))
.findFirst()
.orElseThrow(); //get the enum constant TO_DATE
Field defaultFormatStr = classConfigParam.getDeclaredField("defaultFormatStr"); //get the enum private field defaultFormatStr
defaultFormatStr.setAccessible(true);
defaultFormatStr.set(toDateEnumConstant, "YYYY-MM-DD"); //change with my date format used by production oracle DB.
} catch (Exception e) {
throw new UnsupportedOperationException(
"The current H2 version doesn't support this workaround. Tested with version 1.4.200", e);
}
}

validateDateTimeRange tag for Oracle MAF

I'm trying to implement FROM and TO Date validation in Oracle MAF form.
In ADF I have seen the tag some thing like <af:validateDateTimeRange minimum="" maximum=""/>. From this blog you can get more details, It can be implemented in ADF application.
But I could't find such tag in Oracle MAF. Can you please suggest me, if you got any link to support this requirement?
you would need to use a value change listener. There is no equivalent tag in MAF
Frank
As suggested by Frank, below is the workaround to achieve this.
AMX Page:
<amx:inputDate value="#{bindings.inspFromDate.inputValue}" label="From Date" showRequired="true" inputType="datetime" valueChangeListener="#{validationBean.dateValidation}"/>
<amx:inputDate value="#{bindings.inspToDate.inputValue}" label="To Date" showRequired="true" inputType="datetime" valueChangeListener="#{validationBean.dateValidation}"/>
ValidationBean.java
public void dateValidation(ValueChangeEvent valueChangeEvent) throws ParseException {
String fromDate = (String) AdfmfJavaUtilities.evaluateELExpression("#{bindings.inspFromDate.inputValue}");
String toDate = (String) AdfmfJavaUtilities.evaluateELExpression("#{bindings.inspToDate.inputValue}");
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
formatter.setTimeZone(TimeZone.getTimeZone("IST"));
if (fromDate != null && !fromDate.isEmpty() && toDate != null && !toDate.isEmpty()) {
java.util.Date inputFromDate = formatter.parse(fromDate);
java.sql.Timestamp formattedFromDate = new Timestamp(inputFromDate.getTime());
java.util.Date inputToDate = formatter.parse(toDate);
java.sql.Timestamp formattedToDate = new Timestamp(inputToDate.getTime());
if (formattedFromDate.compareTo(formattedToDate) > 0) {
System.out.println("fromDate is greater than toDate");
throw new AdfException("From Date should be less than To Date.!", AdfException.INFO);
} else if (formattedFromDate.compareTo(formattedToDate) < 0) {
System.out.println("fromDate is less than toDate");
} else if (formattedFromDate.compareTo(formattedToDate) == 0) {
System.out.println("fromDate is equal to toDate");
}
}
}
This method will get both from date and to date from the front screen and convert into timestamp format to validate which is greater.
If From Date is greater than To Date, then it will show you the alert by saying that "From Date should be less than To Date.!". Below is the screenshot, how it will render in the front screen.
Hope this helps some one.!

MongoTemplate find by date conversion

I am trying to convert the following query:
{ "cd" : { "$lte" : ISODate("2013-06-30T09:12:29Z") , "$gte" : ISODate("2013-06-11T09:12:29Z")}}
To use with MongoTemplate and Query.
At the moment i am doing and approach like:
Query query = new Query();
query.addCriteria(Criteria.where("cd").lte(request.getTo()).gte(request.getFrom()));
mongoTemplate.find(query,MyDesiredEntity.class)
But the query above returns no results when the first one returns around 15 which it should(request.getTo and request.getFrom are java.util.Date).
Is there a way to achieve this with org.springframework.data.mongodb.core.query.Query
I got this to work by reversing the lte and gte calls. I wrote a test to show it working:
#Test
public void shouldBeAbleToQueryBetweenTwoDates() throws Exception {
// setup
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss'Z'");
MongoTemplate mongoTemplate = new MongoTemplate(new Mongo(), "TheDatabase");
DBCollection collection = mongoTemplate.getCollection("myObject");
// cleanup
collection.drop();
// date that should match
Date expectedDate = dateFormat.parse("2013-06-12T00:00:00Z");
collection.insert(new BasicDBObject("cd", expectedDate));
// date that should not match (it's last year)
collection.insert(new BasicDBObject("cd", dateFormat.parse("2012-06-12T00:00:00Z")));
// create and execute the query
final Date to = dateFormat.parse("2013-06-30T09:12:29Z");
final Date from = dateFormat.parse("2013-06-11T09:12:29Z");
Query query = new Query();
query.addCriteria(Criteria.where("cd").gte(from).lte(to));
// check it returned what we expected
List<MyObject> basicDBObjects = mongoTemplate.find(query, MyObject.class);
Assert.assertEquals(1, basicDBObjects.size());
Assert.assertEquals(expectedDate, basicDBObjects.get(0).cd);
}
Notes:
This is TestNG not JUnit
I'm using SimpleDateFormat just to make testing of dates easier and (maybe) more readable
The main thing to note is:
query.addCriteria(Criteria.where("cd").gte(from).lte(to));
Before I reversed the order of the lte and gte the query was returning nothing.

DATE handiling from JSP to JAVA to PSQL and back

I am having a problem handling date variables when I write to PostgreSQL using JSP forms. There has been some great tips but still can not get it right. I believe that I am passing a String from JSP to JAVA where it is a Date "setter" and "getter" writing to PSQL on a "date without time zone" column.
Here is parts of the JSP code related to the Date:
.... (some code) ....
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm");
.... (mode code) ....
<%
if (action.equals("add")) {
.
.
.
newCampaign.setCampempDate(dateFormat.parse(request.getParameter("campemp")));
newCampaign.add();
}
%>
.... (more code) ....
<input name="campemp" type="text" class="datePickBox" id="campemp"
onBlur="javascript:checkFormat(this)" value="<%= defaultCampaign.getCampempDate() != null
? dateFormat.format(defaultCampaign.getCampempDate()) : dateFormat.format(new
java.util.Date()) %>" size=20>
.... (rest of code) ....
It is important to mention that on the input I am also using a calendar that passes the date with the correct format... this is another reason I am using a date field on the JSP side.
On the JAVA side:
.... (some code) ....
private java.util.Date campemp= null;
private SimpleDateFormat userDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
... (more code) ... ++ Set and Get ++
public void setCampempDate(java.util.Date aCampemp) {
this.campemp= aCampemp;
}
public java.util.Date getCampempDate() {
return this.campemp;
}
... (more code) ... ++ LOAD ++
public void load(ResultSet rs) throws SQLException {
this.setId(rs.getLong("campkeydbid"));
.
.
this.setCampempDate(rs.getDate("campemp"));
}
... (more code) ... ++ WRITE TO DB ++
public boolean add() throws SQLException {
boolean success = false;
if (costingEnabled) {
String call = "select " + getStoredProcedureMapper().getPrefix() + "_Add(?,?,?,?,?,?,?,?,?,?)";
DataSource ds = PoolMan.findDataSource("mydatabase");
Connection conn = null;
try {
conn = ds.getConnection();
PreparedStatement pst = conn.prepareStatement(call);
.
.
pst.setTimestamp(10, new Timestamp(this.getCampempDate().getTime()));
ResultSet rs = pst.executeQuery();
if (rs.next()) {
.
.
... (more code) ...
The "_Add" on the stored procedure is correct as it works if I "hardcode" the date on the pst.SetTimestamp
The error I am getting is the following:
org.apache.jasper.JasperException: Unable to convert string "04/07/2012 19:12" to class "java.util.Date" for attribute "campemp": Property Editor not registered with the PropertyEditorManager
Any ideas on a workaround to parse the String to Date without affecting the DB date field and JSP input will be greatly appreciated.. thank you very much.
Regards,
Rob
org.apache.jasper.JasperException: Unable to convert string "04/07/2012 19:12" to class "java.util.Date" for attribute "campemp": Property Editor not registered with the PropertyEditorManager
You are passing Date in String in 04/07/2012 19:12 format so you need to use
dd/MM/yyyy HH:mm
From the code you posted, It seems you are using
private SimpleDateFormat userDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
as format in SimpleDateFormat

Mongo ISODate query in Java

I have a mongo query to be executed :
query = { "dateField" : { "$gte" : ISODate('2011-11-10T07:45:32.962Z') } }
When I do a db.Collection.find(query) on the mongo shell, I am able to retrieve the results.
How could I query this using Java ? I tried constructing a String based on the Date parameter.
But in the process of building the String, it eventually gets passed as "ISODate('2011-11-10T07:45:32.962Z')" instead of ISODate('2011-11-10T07:45:32.962Z') (without the surrounding quotes).
What would be the best way to construct this query using the Java API ?
Thanks !
Use a regular Java Date--also I recommend the QueryBuilder:
Date d = new Date(); // or make a date out of a string...
DBObject query = QueryBuilder.start().put("dateField").greaterThanEquals(d).get();
I have search lot and spend more than hour in finding how to get data when having ISODate in mongo model.
As the default constructor for date is deprecated so it was not working in my case.
BasicDBObject searchQuery = new BasicDBObject("_id" , 1);
try {
searchQuery.append("timestamp",BasicDBObjectBuilder.start( "$gte",new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS\'Z\'").parse("2015-12-07T10:38:17.498Z")).get());
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Categories