Spring Querying DateTime by Date - java

I am fairly new to spring so maybe I am missing the wrong terminology and that is the reason why my searches brought nothing up.
The Query I am looking for should Take a parent object and remove all Child objects where a timestamp is not of a specific date.
Parent Id field1 field2
Child: Id parentId field 1 timestamp (datetime)
I tried several different approaches but nothing seems to work.
Alternatively I could try something like:
FindAllChildsByIdAndTimestamp(int id, Date date)
And fill a empty Parent with the data. But event hat does not work.
Any Idea what i am doing wrong?
Best and Thank you

You don't even need to bring a parent into this. All you need to do is to create a query on a child table and generate a query on that table with where clause would be parentId is and timestamp is . You mentioned that you are using Spring (which version BTW?) but didn't say what do you use to access your DB (Spring Data, Hibernate, JPA, JBC?) Also which DB and which version? I will give you example in Hibernate:
sessionFactory.getCurrentSession().createCriteria(Child.class)
.add(Restrictions.eq("parentId", yourParentId))
.add(Restrictions.gt("timestamp", date1))
.add(Restrictions.le("timestamp", date2))
.list();
date1 is midnight of your day and date2 is midnight of the following day. This should give you the list of your children

I solved the problem by seperating the two requests.
public interface ChildRepository extends CrudRepository<Child, Serializable> {
List<child> findAllBytimeStampBetweenAndParent(Date dayBegin, Date dayEnd, Parent parent);
And then attributed it to the parent
Parent parent = this.getById(id);
// Convert Date Type
DateTime dayTimeEnd = new DateTime(date);
dayTimeEnd = dayTimeEnd.plusHours(23);
dayTimeEnd = dayTimeEnd.plusMinutes(55);
Date dayEnd = dayTimeEnd.toDate();
// Get all Tracking Data of this Date
List<Child> ChildList = this.childRepository.findAllBytimeStampBetweenAndParent(date, dayEnd, parent);
as an alternative i could have used direct queries.
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/

Related

timestamp type changes to date type in hibernate query

I have an entity named A, which has a createdDate with this type #Temporal(TemporalType.TIMESTAMP).
I tried to retrieve all the rows having a certain createdDate. I attached a certain date to the request and I printed that date, it looks fine like "2021-02-11 12:14:02.425", which has all the values up to millisecond.
But the sql from hibernate, the value for createdDate in the where clause is set as '11-Feb-21'. Therefore, I do not find any rows because the createdDate is saved as 2021-02-11 12:14:02.425 in the db.
public Response getByCreatedDate(Request req) {
List<AResponse> aList = aRepository.findByIdAndCreatedDate(req.getId(), req.getCreatedDate());
}
I am new for Hibernate, I tried find some useful information about it but could not. Do I have to explicitly create a new Date with those specific date and time and send it to the method 'findByIdAndCreatedDate'? If anyone has the same experience, could you give some information about it?

MongoDB, common part of 2 Querys

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.

Update with Server time For Spring Mongo

How to update entity with Mongo server time
Query query = new Query(new Criteria("id").is(user.getId()));
Update update = new Update().set("text", text)
.set("timeStamp", ??? );
This field should only be updated in one method
#LastModifiedDate It does not suit me?
timeStamp is LocalDateTime
You want either .currentDate() or .currentTimestamp() depending on your intended storage result.
Update update = new Update().set("text", text)
.currentDate("timeStamp");
Which actually corresponds to the $currentDate BSON update modifier and all the same usage, being of { $type: "date" } or { $type: "timestamp" } in it's options for the respective methods.
These are BSON Date values and therefore UTC Time.
Get the idea of Local time out of your head, since it has no business being stored in a database which can be accessed around the world.

Hibernate Criteria for Time > 0

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)));

Finding the recently deleted entities using Hibernate envers

So my problem is that I need to find all the recently deleted entities of a particular class, that is the entities which have been deleted since a particular timestamp. Specifically, I want to find entities deleted within the last hour.
All my entities have a created and updated timestamp which I maintain correctly with a listener:
#NotNull
#Column(name = "updated")
#Type(type="org.joda.time.contrib.hibernate.PersistentDateTime")
private DateTime updated;
I also use Envers and annotate my entities.
So to guess, my query should start like this:
// Query for deleted bookings
AuditReader reader = AuditReaderFactory.get(entityManager);
AuditQuery query = reader.createQuery()
.forRevisionsOfEntity(Booking.class, false, true)
but I don't know what to put here to find the deleted Booking's since a DateTime.
First, get a timestamp for one hour ago (in milliseconds):
long timestamp = (System.getCurrentTimeMillis()) - (60*60*1000);
Then you can query relative to the timestamp:
AuditReader reader = AuditReaderFactory.get(entityManager);
AuditQuery query = reader.createQuery()
.forRevisionsOfEntity(Booking.class, false, true)
.add(AuditEntity.revisionProperty("timestamp").gt(timestamp)
.add(AuditEntity.revisionType().eq(RevisionType.DEL));
List<Object[]> results = query.getResultList();
to get the revision data. Each Object[] has
revision meta data (DefaultRevisionEntity or your own class annotated with #RevisionEntity(CustomRevisionListener.class))
the entity instance (the Booking in this case)
the RevisionType, which we know will always be DEL in this case
I find the Envers API quite limited and sometimes have to turn to use just plain JPA. However, this is not one of those cases, I believe you can achieve your use case by doing the following:
AuditQuery query = reader.createQuery().forRevisionsOfEntity(classType, false, true)
.add(AuditEntity.revisionType().eq(RevisionType.DEL))
.addProjection(AuditEntity.property(ID).distinct())
.add(AuditEntity.revisionNumber().gt(revisionNumber);
The above example uses the revision number but you could easily retrieve the revision number from the start date you are looking for.

Categories

Resources