I am to fix an older project, in which there is a database query gone wrong. In the Table, there is a field
viewTime TIME NOT NULL DEFAULT 0
I need to filter out the rows that actually have 0 as their viewTime:
Criteria query = /* create criteria */;
query.add(Restrictions.gt("viewTime", 0));
However, since viewTime is defined as a Date:
#Temporal(TemporalType.TIME)
private Date viewTime;
I get a casting exception. On the other hand, I have no idea how to create a valid Date object that represents time 0. I can't change the type of the field as well for this.
Any way I can express viewTime > 0 in this Criteria object?
I think you have to compare date object with (00/00/00) but the any API will not produce DATE value like it.
This might your solution convert to null refer this link
It seems to me, that you can try such construction:
Criteria query = /* create criteria */;
query.add(Restrictions.gt("viewTime", new Date(0)));
Related
I got document that looks like this
#Document(collection="myDocument")
public class MyDocument {
#Id
private String id;
private List<Dates> dates;
}
public class Dates{
private String key;
private DateTime value;
}
And OtherDocument is container for DateTime values from various sources, I can't simply make fields like DateTime birthdate; inside MyDocument because I don't know what key will be, they are just some dates that describe MyDocument. Now, I need to create search engine for those values, for example, someone want's to find all MyDocuments with dates that contains:
key : "Birthdate" greater than
value : "1990-01-01 00:00:00 +00:00"
and key : "Mather's birthday" less than
value: "1975-01-01 00:00:00 +00:00"
So, Criteria (using MongoTemplate here) first may look like this
Criteria criteria = Criteria.where("myDocument.dates.value")
.exists(true)
.gt(DateTimeUtil.valueOf("1990-01-01 00:00:00 +00:00")) //just converting String to DateTime here
.and("myDocument.dates.name")
.exists(true)
.all("Birthday"));
And second one:
Criteria criteria = Criteria.where("myDocument.dates.value")
.exists(true)
.lt(DateTimeUtil.valueOf("1975-01-01 00:00:00 +00:00"))
.and("myDocument.dates.name")
.exists(true)
.all("Mather's birthday"));
The problem is, I can't put those both Criteria in one Query, it will cause error. The only soultion I found till now is to make 2 separate Query in that case and then find common part by using
resultA.retainAll(resultB)
But the point is, I don't want to, this database will store a lot of data and those requests will be very frequent. I need this to work fast, and combining 2 lists in pure Java will be slow as hell with that amount of data. Any ideas how to deal with that?
edit#
here is the error thrown when I try to combine 2 Criteria like this in one Query
caught: (java.lang.RuntimeException), msg(json can't serialize type :
class org.joda.time.DateTime) java.lang.RuntimeException: json can't
serialize type : class org.joda.time.DateTime
You can use below code. $and the query together and use $elemMatch to match the dates fields on multiple condition.
Something like
Criteria criteria1 = Criteria.where("dates").
elemMatch(
Criteria.where("value").exists(true).gt(DateTimeUtil.valueOf("1990-01-01 00:00:00 +00:00"))
.and("name").exists(true).all("Birthday")
);
Criteria criteria2 = Criteria.where("dates").
elemMatch(
Criteria.where("value").exists(true).lt(DateTimeUtil.valueOf("1975-01-01 00:00:00 +00:00"))
.and("name").exists(true).all("Mather's birthday")
);
Criteria criteria = new Criteria().andOperator(criteria1, criteria2);
Note: You may still have the problem with joda time conversion.
I fetched data from the oracle database through java code using a query similar to the below:
select min(specDate) from table
The result is supposed to be of type Date.
Since there was no specDate populated for any of the rows in the table, the result was null.
I used this query in my java code and mapped it to Date object using BeanPropertyRowMapper.
The result I got after mapping was the system date or the current date.
Not sure as to why the mapper returned current date instead of null.
Found the reason.
When the BeanPropertyRowMapper was provided with Date.class for mapping,
new Date() is called for instantiation of the class like for any object.
But for Date.class, new Date() returns sysDate.
I have an action in struts2 that will query the database for an object and then copy it with a few changes. Then, it needs to retrieve the new objectID from the copy and create a file called objectID.txt.
Here is relevant the code:
Action Class:
ObjectVO objectVOcopy = objectService.searchObjects(objectId);
//Set the ID to 0 so a new row is added, instead of the current one being updated
objectVOcopy.setObjectId(0);
Date today = new Date();
Timestamp currentTime = new Timestamp(today.getTime());
objectVOcopy.setTimeStamp(currentTime);
//Add copy to database
objectService.addObject(objectVOcopy);
//Get the copy object's ID from the database
int newObjectId = objectService.findObjectId(currentTime);
File inboxFile = new File(parentDirectory.getParent()+"\\folder1\\folder2\\"+newObjectId+".txt");
ObjectDAO
//Retrieve identifying ID of copy object from database
List<ObjectVO> object = getHibernateTemplate().find("from ObjectVO where timeStamp = ?", currentTime);
return object.get(0).getObjectId();
The problem is that more often than not, the ObjectDAO search method will not return anything. When debugging I've noticed that the Timestamp currentTime passed to it is usually about 1-2ms off the value in the database. I have worked around this bug changing the hibernate query to search for objects with a timestamp within 3ms of the one passed, but I'm not sure where this discrepancy is coming from. I'm not recalculating the currentTime; I'm using the same one to retrieve from the database as I am to write to the database. I'm also worried that when I deploy this to another server the discrepancy might be greater. Other than the objectID, this is the only unique identifier so I need to use it to get the copy object.
Does anyone know why this is occuring and is there a better work around than just searching through a range? I'm using Microsoft SQL Server 2008 R2 btw.
Thanks.
Precision in SQL Server's DATETIME data type does not precisely match what you can generate in other languages. SQL Server rounds to the nearest 0.003 - this is why you can say:
DECLARE #d DATETIME = '20120821 23:59:59.997';
SELECT #d;
Result:
2012-08-21 23:59:59.997
Then try:
DECLARE #d DATETIME = '20120821 23:59:59.999';
SELECT #d;
Result:
2012-08-22 00:00:00.000
Since you are using SQL Server 2008 R2, you should make sure to use the DATETIME2 data type instead of DATETIME.
That said, #RedFilter makes a good point - why are you relying on the time stamp when you can use the generated ID instead?
This feels wrong.
Other than the objectID, this is the only unique identifier
Databases have the concept of a unique identifier for a reason. You should really use that to retrieve an instance of your object.
You can use the get method on the Hibernate session and take advantage of the session and second level caches as well.
With your approach you execute a query everytime you retrieve your object.
I am using Compass to make queries on data inside in memory data structure. It works fine for searching String and enum values, now I want to search dates.
Search criteria are annotated by #SearchRestriction annotation. Example about someDate:
#SearchRestriction(path="fooBar.someDate" type = SearchRestrictionType.EQUAL)
String someDate;
At searchable data SomeDate is annotated like the following:
#SearchableProperty
Date someDate;
SomeDate inside the searchable data is generated with new Date();) and query String is given as 20120802.
Situation on debugger:
This code generates queries like this:
someDate:20120802
Here someDate is the name of the field I am looking for and 20120802 is a date in order yyyyMMdd.
Problem:
No results is returned, when this query is run. I get an empty list. The Date in query is the same as in the Date object.
What is wrong??
Is this wrong way to search Dates with Compass? I can find only range queries about Date, but a search with exact Date or part of exact Date I cannot find.
You need to specify the format for Searchable property [Date]
#SearchableProperty(format = "yyyyMMdd")
To some extent, it relates to Grails: Lucene, Compass Query Builder and date ranges
I believe this has been a bug/problem in SQL 2000/2005 ... If my results have null on DATETIME column, i get
com.microsoft.sqlserver.jdbc.sqlserverexception:
the conversion from int to date is unsupported
when i use sql.getDate("ColumnName") ...
Any solutions to this?
[EDIT]
Hi all thanks for your inputs, below is my SQL query
select p.planno as PlanNumber,
t.TrancheID as TrancheID,
t.tranchestartdate as TrancheStartDate,
t.tranchereasoncode as TrancheReasonCode,
ai.ArrayItemDecode TrancheReasonDescription,
t.trancheuwstage as UnderwritingStatusCode
from plan_ p
inner join tranche t
on t.planno = p.planno
and t.trancheuwstage in ( 2, 4 )
and p.planno = '040000000X6'
inner join arrayitem ai
on ai.ArrayNm = 'arrTraReas'
and ai.ArrayItemCode = t.tranchereasoncode;
and the culprit here is tranchestartdate which is a DATETIME. I can't really add anything to tabel as i'm not allowed to change existing table structures, this is a big system. Perhaps i can do the casting in my SQL? I'm not quite sure if this is definitely a null problem.. Can one debug/watch through the ResultSet and check if any data was retrieved before i call getDate()?
[/EIDT]
If your application (or drivers) cannot handle null dates then the easiest thing might be to use ISNULL(field, <null replacement date>) and check for the null replacement date in code. This approach uses a magic number (date) to indicate null values, true. It's not pretty but it is quick and straightforward.
Can't you use coalesce for this?
http://msdn.microsoft.com/en-us/library/ms190349.aspx
Are you selecting the datetime from a field or constructing it dynamically in your SELECT? you may have to CAST the result.
See this article