Grails accessing data where dates equal in database first mode - grails

I'm returning to Grails after a year hiatus while I worked for .Net shop. I had always programmed Grails in code first mode. My newest project is database first, and I thought I was ready. I have a simple calendar table in my MySql database:
commit;CREATE TABLE `Calendar` (
`ID` bigint(20) NOT NULL,
`Title` varchar(200) NOT NULL,
`EventDate` date NOT NULL,
`StartTime` time DEFAULT NULL,
`EndTime` time DEFAULT NULL,
`Location` varchar(500) NOT NULL,
`version` int(11) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
With the following data in the table:
insert into Calendar (Title, EventDate, StartTime, EndTime, Location, version)
values ('Summer 2016 Garage Sale', '2016-07-23', '7:00 ', '19:00', 'Lodge', 0);
insert into Calendar (Title, EventDate, StartTime, EndTime, Location, version)
values ('August 2016 Member Meeting', '2016-08-03', '19:00', '20:00', 'Lodge', 0);
commit;
My calendar class in Grails looks like:
package plaquemineelks
import java.sql.Time
import grails.validation.Validateable
#Validateable
class Calendar {
Long id
Integer version
String title
Date eventDate
Time startTime
Time endTime
String location
static constraints = {
title (blank: false)
eventDate (blank: false)
location (blank: false)
}
static mapping = {
table "Calendar"
id column: "ID"
version column: "version"
eventDate column: "EventDate"
startTime column: "StartTime"
endTime column: "EndTime"
location column: "Location"
}
}
My controller looks like:
package plaquemineelks
class CalendarController {
def index() { }
def getByDate(String EventDate) {
def Date newDate = Date.parse("mm/dd/yyyy", EventDate)
def results = Calendar.findAllByEventDate(newDate)
render(contentType: 'text/json') {[
'results': results,
'status': results ? "OK" : "Nothing present"
]}
}
}
When I run the app and open the URI
http://localhost:8080/PlaquemineElks/Calendar/getByDate?EventDate=07/23/2016
My Json looks like:
{"results":[],"status":"Nothing present"}
I have tried a variety of formats, etc. for the date, keeping it groovy. I'm sure I'm missing something simple.
Thanks for any assistance.

You are inserting data to your table using sql query which means by default the StartDate contains date only and 00:00:00 for timestamp. Otherwise it will consider the timezone also if you insert into it using GORM.
First thing that you need to do is set the time zone to UTC for your application. In Bootstrap.grooy:
TimeZone.setDefault(TimeZone.getTimeZone('UTC'))
Secondly the format mm/dd/yyyy that you are using to parse the date is wrong, it should be: MM/dd/yyyy.
println Date.parse("mm/dd/yyyy", "07/23/2016")
Sat Jan 23 00:07:00 UTC 2016 //wrong
println Date.parse("MM/dd/yyyy", "07/23/2016")
Sat Jul 23 00:00:00 UTC 2016 //correct

Related

when datetime objects casted to string, language of month name not match with culture info

I set culture info to turkish, but when datetime object casted to string(""+h.DogumTarihi) it looks like; Jan.26.1989
System.Threading.Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("tr-TR");
EvlilikRaporuVM mdl = (from r in raporRepo
join h in hastaRepo on r.HastaTc equals h.HastaTc
select new EvlilikRaporuVM
{
ID = Id,
BirthDate = "" + h.DogumTarihi,
...
how to force datetime object to get language info from current culture?
You need to specify the CurrentCulture:
System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("tr-TR");
With this, the following:
Console.WriteLine(DateTime.Now.ToLongDateString());
Outputs:
25 Eylül 2018 Salı

SDN5/OGM3 compare java.util.Date at Cypher query

I have the following entity:
#NodeEntity
public class Action {
...
#Index(unique = false)
private Date createDate;
...
}
I need to get the last Action that was created during some previous period of time.
In order to do this I have implemented the following repository method:
#Repository
public interface ActionRepository {
#Query("MATCH (a:Action)-[:CREATED_BY]->(u:User) WHERE a.entityType = {entityType} AND a.createDate <= {minCreateDate} AND u.id = {userId} RETURN a ORDER BY a.createDate DESC LIMIT 1")
Action findLastByEntityTypeForUser(#Param("entityType") String entityType, #Param("minCreateDate") Date minCreateDate, #Param("userId") Long userId);
}
I use the following code to test this method:
decisionDao.create("Decision2", "Decision2 description", null, false, null, user1);
Date minStartDate = DateUtils.addMilliseconds(new Date(), -1000 * 60);
Action user1LastAction = actionRepository.findLastByEntityTypeForUser(Decision.class.getSimpleName(), minStartDate, user1.getId());
assertNotNull(user1LastAction); // test fails here because of NPE
but without this part of the Cypher query AND a.createDate <= {minCreateDate} I can successfully find Action instance.
At Neo4j level my data looks like:
{
"updateDate":"2017-10-08T12:21:39.15
3Z",
"entityName":"General",
"en
tityType":"CriterionGroup",
"entityId":1,
"id":1,
"type":"CREATE",
"createDate":"2017-10-08T12:21:39.153Z"
}
What am I doing wrong and how to properly compare the dates with SDN/OGM and Cypher?
Also, is there any way to tell SDN/OGM to store java.util.Date object as long milliseconds and as String?
the minCreateDate parameter you use for your find-Method is of type Date and the createDate property is a String. So, this part a.createDate <= {minCreateDate} is basically comparing the String representation of minCreateDate and the String property createDate.
In my projects, I usually save the dates and timestamps as long both in the database and in my code.
Or even better, if the date attributes are crucial for my application, I'm using the "Time Tree Model" approach: https://graphaware.com/neo4j/2014/08/20/graphaware-neo4j-timetree.html

Ember.js Query Parameters - Update query results when creating a model

I am using the new query-params in Ember.js to filter entries by date. I have added a field to add new entries, with the date being automatically assigned as the query date. When a new entry is added it only shows up on the page when I refresh. Is there any way to retrigger the query without changing the query itself?
Controller: (simplified)
queryParams: 'date'
date: null
filteredEntries: ( ->
date = #get('date')
model = #get('model')
if (date)
return entries.filterProperty('date', date)
else
return entries
).property('date', 'model')
actions:
createEntry: ->
entry = #store.createRecord('entry', { date: #get('date') })
entry.save()
I also tried this, but it didn't work:
entry.save().then -> this.transitionTo({queryParams: { date: #get('date')}})
I think this is what you are looking for (in your route):
App.MyRoute = Ember.Route.extend({
queryParams: {
date: {
refreshModel: true
}
},
});
This will refresh your model everytime the value of date changes.

Working with dates in breeze

I'm having some trouble working with dates.
I have an object with a date field:
public DateTime FechaInicio{get; set;}
This definition generates the following field in the database:
FechaInicio datetime not null
Making the request to the web service I get the date ( in the JSON ) in the following format:
"FechaInicio": "1982-12-02T00: 00:00"
And calling FechaInicio() on tne entity returns a javascript Date object.
Creating a new entity I get the following value:
createPalanca var = function () {
MetadataStore var = manager.metadataStore;
metadataStore.getEntityType palancaType = var ("Toggle");
palancaType.createEntity newPalanca = var ();
manager.addEntity (newPalanca);
//Here: newPalanca.FechaInicio () has the value in this format: 1355313343214
//Expected Date object here
newPalanca return;
};
After all, my real question is: What format should I use to assign new values ​​to date type fields?
Edit:
After doing some tests, I noticed that if I assign a Date object to the property, everything seems fine until we got to this line:
saveBundleStringified var = JSON.stringify (saveBundle);
saveBundle content is:
FechaInicio: Thu Dec 20 2012 00:00:00 GMT+0100 (Hora estándar romance)
and the saveBundleStringified:
"FechaInicio": "2012-12-19T23:00:00.000Z" <- I guess this is utc format
What finally is stored in the database is: 2012-12-19 23:00:00.0000000
When the result of the call to SaveChanges are returned , they are merged with the entities in cache at the function updateEntity which does this check: if (!core.isDate(val)) that returns false.
As a consequence it is created a new Date object with the wrong date:
function fastDateParse(y, m, d, h, i, s, ms){ //2012 12 19 23 00 00 ""
return new Date(y, m - 1, d, h || 0, i || 0, s || 0, ms || 0);
}
Correct me if I'm wrong, but I think that's the problem.
Sorry for taking so long...
There were bugs with Breeze's DateTime timezone serialization and the default DateTime values used for newly constructed entities with non-nullable date fields. These are fixed as of v 0.77.2. Please confirm if this set of fixes works for you.
And thanks for finding these.
And to answer your question, all date properties on your object should be set to javascript Dates. Breeze should handle all of the serialization issues properly.
Dates always scare me. My immediate instinct is that the browser and server are not on the same TimeZone; how that could be I don't know. In any case, it's bound to happen and I recall all kinds of fundamental problems with coordinating client and server on datetime. I think the usual recommendation has always been to keep everything in UTC and adjust what you display to the user in local time.
I rather doubt this is a helpful answer. I'm not sure what part Breeze should play in resolving this. Would welcome a suggestion that we can circulate and build consensus around.
Also can you clarify this statement:
When the result of the call to SaveChanges are returned , they are merged with the entities in cache at the function updateEntity which does this check: if (!core.isDate(val)) that returns false. As a consequence it is created a new Date object with the wrong date
What do you mean by "the wrong date"? And are you saying that Breeze thinks the incoming date value is in an invalid format (as opposed to being a date other than the one you expected)?
Yes, #Sascha, Breeze is using the Web Api standard for JSON formatting (Json.Net) and it is set for ISO8601 format as opposed to the wacky Microsoft format (which escapes me as I write this).
Breeze/Web Api seem to need the dates in some special format (ISO8601). Any other format did not work for me. moment.js solved the problem for me with setting and reading. Formatting is also nicely done if you use Knockout to display the date with a special binding.
entity.someDate(moment().utc().toDate()) // example
and it works.
You could also use this:
Date.prototype.setISO8601 = function(string) {
var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
"(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" +
"(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
var d = string.match(new RegExp(regexp));
var offset = 0;
var date = new Date(d[1], 0, 1);
if (d[3]) {
date.setMonth(d[3] - 1);
}
if (d[5]) {
date.setDate(d[5]);
}
if (d[7]) {
date.setHours(d[7]);
}
if (d[8]) {
date.setMinutes(d[8]);
}
if (d[10]) {
date.setSeconds(d[10]);
}
if (d[12]) {
date.setMilliseconds(Number("0." + d[12]) * 1000);
}
if (d[14]) {
offset = (Number(d[16]) * 60) + Number(d[17]);
offset *= ((d[15] == '-') ? 1 : -1);
}
offset -= date.getTimezoneOffset();
time = (Number(date) + (offset * 60 * 1000));
this.setTime(Number(time));
};

No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

In controller :
AssocCovList.addAssoc(3, 4)
In Domain :
package com.org.domain
class AssocCovList {
Integer id
Integer association_id
Integer cov_list_id
Date edit_date
static belongsTo = [association : Association, cov_list : CoverageList]
static constraints = {
edit_date(nullable:true )
}
static mapping = {
table 'assoc_cov_list'
version false
columns {
id column : 'ASSOC_COV_LIST_ID'
association_id column : 'ASSOCIATION_ID'
cov_list_id column : 'COV_LIST_ID'
edit_date column : 'EDIT_DATE'
}
}
def static addAssoc(3, 4){
def aclist = new AssocCovList(association_id:3,cov_list_id:4, edit_date:new Date())
aclist.save()
}
Here is sql structure :
CREATE TABLE omni.assoc_cov_list (
ASSOC_COV_LIST_ID int(11) NOT NULL auto_increment,
ASSOCIATION_ID smallint(6) NOT NULL default '0',
COV_LIST_ID int(11) NOT NULL default '0',
EDIT_DATE date default NULL,
PRIMARY KEY (ASSOC_COV_LIST_ID),
UNIQUE KEY ASSOC_COV_LIST_I2 (ASSOCIATION_ID,COV_LIST_ID),
KEY ASSOC_COV_LIST_FK1 (COV_LIST_ID),
KEY ASSOC_COV_LIST_FK2 (ASSOCIATION_ID)
) ENGINE=InnoDB AUTO_INCREMENT=9584 DEFAULT CHARSET=utf8;
This was returning No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
Why it is returning null object?
I am able to update and delete the record(s). Not working for new record.
Wait a minute... I think the domain class itself is not the right place to call a save() on itself !
This should be done at the controller or service level. Can you give a try to this :
In your domain class :
def static addAssoc(<yourargs>){
return new AssocList(/*Whatever arguments you pass */)
}
In your controller :
AssocCovList.addAssoc(<yourargs>).save()
You defined AssocCovList to have the following properties:
Integer id
Integer association_id
Integer cov_list_id
Date edit_date
And then try to create a new AssocCovList(association_id:3) using only the association_id. However, by default all properties are both persistent and required. To create a new AssocCovList you would need to provide also the id, cov_list_id and edit_date.

Resources