I have an entity with two columns:
// time when the event happened (stored in UTC)
#Temporal(TemporalType.TIMESTAMP)
private Date eventTime;
// timezone offset in milliseconds
// so local millis are eventTime.getTime() + offset
#Basic
private int offset;
It appears that in JPQL queries I can't use something like WHERE eventTime + offset > :parameter. But is it possible to work around by casting eventTime to a long in some way? Of course, there is an option of using native queries...
EDIT:
It isn't supported in the standard and isn't mentioned in OpenJPA documentation, so probably not possible at the moment.
It may not be possible for you to modify the table, but can you possibly just add another column which is the computed timestamp with offset? Then just base all of your queries off of that? It will probably yield better performance, as well.
Another way I've solved problems like this is to create a SQL view and and create a different #Entity based on that view. I have done this when I need a lot of complex computations and don't want all of that complexity in the code itself. This is useful when you have other non-JPA based applications that want to get at the same information (such as a reporting engine). While this solution ends up using a SQL view, it allows your Java/JPA code to not have to deal with native queries.
What I've done in similar situations before is to declare the setters/getters private or protected and then have public #Transient getters to perform the desired calculation.
This solves all programmatic issues. For desired jpa sql you'll need to perform the appropriate calculation in the query.
Related
I am quite new to JPA. I have a particular repository that uses the keys that have parts that are set by the caller and some values that are automatically calculated using these values. There is a need for this :)
Since the keys and entities are simple Java classes it appears to me that I need to put my code that modifies the key (or substitutes it with an internal one with additional values) is the repository implementation. However I do not think that copying the code from SimpleJpaRepository to my custom repositories is a good idea...I think that something should be possible with the entity manager. Basically what I need is proxy that gets called every time something like find() or delete() is called, takes the entity, updates its key, passes the call over to the real repository implementation.
Could someone point me to the right direction or an example that does something similar?
Thanks!
In JPA, you have a bunch of events for this, just chose the one that suits you best. It looks like you are looking for #PrePersist.
http://www.objectdb.com/api/java/jpa/annotations/callback
That said, if the data of these fields is calculated based only in the data of the other fields, it goes against database normalization. A more sensate approach would be make the calculated field #Transient and provide only the getters, that will calculate the values based in the persistent fields.
I am using JPA/JFreeChart to display data I collected with a microcontroller, however, I measure 14 sensors every 10 seconds. I have been measuring for over 2 months and I have over 7000000 sets of data.
Now to my actual problem, since I don't want to load 7000000 rows every time I start my program, I only want to use average values by minutes/hours. I have thought of using a NamedQuery however I don't know how to keep the relationship within it and make JPA use it since up until now the loading of the data has been done by JPA itself. Maybe I can just solve this by adding more annotations to this?
#OneToMany(mappedBy="sensor")
#OrderBy("timestamp ASC")
public List<Value> getValues() {
return this.values;
}
Thanks in advance!
Best Regards
Straight JPA does not allow filtering results, since this means that the entity's relationship no longer reflects exactly what is in the database, and it would have to standardize behavior on what is done when adding an entity to the relationship that isn't in the collection, but already exists in the database.
The easiest way for this mapping though would be to mark the attribute as #Transient. You can then use the get method to read the values from the database using when needed, and cache them in the entity if you want.
Many providers do allow adding filters to the queries used to bring in mappings, for instance EclipseLink allows setting #AdditionalCriteria on the mapping as described here: http://wiki.eclipse.org/EclipseLink/Development/AdditionalCriteria Or you can modify the mapping directly as shown here: http://wiki.eclipse.org/EclipseLink/Examples/JPA/MappingSelectionCriteria
Does anyone knows if morphia supports automatic timestamp for create/update of documents in a collection in mongodb during its create/modify operations.
I have already come to know that this support is not available in mongodb. I would like to know if there is any way to get the last access/update time of data or documents in morphia driver.
Thanks,
sadish
I'm generally using a base entity, which all other entities extend. It provides the ObjectId, creation date, last change date, a disabled flag,...
The relevant code snippets look like this:
protected Date creationDate;
protected Date lastChange;
// Getters and setters or final setters which don't do anything,
// if you only want to allow the entity to update the values
#PrePersist
public void prePersist() {
creationDate = (creationDate == null) ? new Date() : creationDate;
lastChange = (lastChange == null) ? creationDate : new Date();
}
Sorry in advance if this isn't the exact answer you're looking for. But the short answer is no.
There appears to be no API in the latest Morphia which supports that operation. Maybe there is a bug opened to support this. In the meantime, you should use your favorite constructor for java.util.Date or java.sql.Timestamp.
The source code for Morphia has the appropriate converter built in to handle this TimestampConverter.java.
Only tangentially related. If your reason for using $currentDate is to avoid clock skew problems among multiple hosts, then you're barking up the wrong tree. Though not explicitly stated in the $currentDate documentation, it is documented that MongoDB does nothing to address clock skew among various hosts. This can be found in the documentation for ObjectId.getTimestamp(). Therefore, the usage of $currentDate is going to provide little benefit as opposed to time-stamping in the client side.
I have a Question object which has List of Comment objects with #OneToMany mapping. The Question object has a fetchComments(int offset, int pageSize) method to fetch comments for a given question.
I want to paginate the comments by fetching a limited amount of them at a time.
If I write a Query object then I can set record offset and maximum records to fetch with Query.setFirstResult(int offset) and Query.setMaxResults(int numberOfResults). But my question is how(if possible) can I achieve the same result without having to write a Query i.e. with simple annotation or property. More clearly, I need to know if there is something like
#OneToMany(cascade = CascadeType.ALL)
#Paginate(offset = x,maxresult = y)//is this kind of annotation available?
private List<Comment> comments;
I have read that #Basic(fetch = FetchType.LAZY) only loads the records needed at runtime, but I won't have control to the number of records fetched there.
I'm new to JPA. So please consider if I've missed something really simple.
No, there is no such a functionality in JPA. Also concept itself is bit confusing. With your example offset (and maxresult as well) is compile time constant and that does not serve pagination purpose too well. Also in general JPA annotations in entities define structure, not the context dependent result (for that need there is queries).
If fetching entities when they are accessed in list is enough and if you are using Hibernate, then closest you can get is extra #LazyCollection:
#org.hibernate.annotations.LazyCollection(LazyCollectionOption.EXTRA)
I need a consensus on the practice of persisting timestamps, specifically on the pros & cons of using java.util.Date compared to using long.
Scope of this discussion:
Performance
Querying Flexibility (e.g. date range)
Any hazards in coding and querying
Portability (e.g. migration to other DB)
About myself:
I consider myself to be a beginner in JPA, dabbling in it once in a while, not being able to apply it into production level projects until now. In my current project, I commit myself to use ObjectDB (embedded) through JPA calls.
The following class demonstrates 3 possible methods for persisting timestamps in JPA:
#Entity
public class Timestamps {
private java.sql.Timestamp ts1;
private #Temporal(TemporalType.TIMESTAMP) java.util.Date ts2;
private long ts3;
:
}
Regarding performance and memory consumption, ts3 is a bit more efficient.
ts3 may be less convenient to use than ts1 and ts2 (in ObjectDB Database Explorer, reports, etc.).
Basic queries such as retrieval by date range are supported for all the three, but extracting date and time parts (YEAR, MONTH, etc.) in queries is not supported for ts3.
All these forms are expected to be portable.
ts1 and ts2 are practically equivalent.
More details are provided in the ObjectDB manual.
In the documentation of java it looks like timestamp is closer related to java.util.date
http://docs.oracle.com/javase/1.4.2/docs/api/java/sql/Timestamp.html
additionally if you care about the semantic of your code, a timestamp is a date.
You should be aware about java.sql.Timestamp's fact before using it:
There are some classes in the Java platform libraries that do extend an instantiable
class and add a value component. For example, java.sql.Timestamp
extends java.util.Date and adds a nanoseconds field. The equals implementation
for Timestamp does violate symmetry and can cause erratic behavior if
Timestamp and Date objects are used in the same collection or are otherwise intermixed.
The Timestamp class has a disclaimer cautioning programmers against
mixing dates and timestamps. While you won’t get into trouble as long as you
keep them separate, there’s nothing to prevent you from mixing them, and the
resulting errors can be hard to debug. This behavior of the Timestamp class was a
mistake and should not be emulated. (Bloch, Effective Java, 2nd Ed.)