Intercepting JPA query to calculate the key fields - jpa

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.

Related

JPA Lazy Fetch Custom Query

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

Preventing duplicates in MongoDB using Spring Data (Spring Roo)

I have been trying to get my head wrapped around MongoDB, as it's used by Spring, so I decided to start a little project in Spring Roo.
In my project, I am storing my User Login data to MongoDB. The trouble is that the registration process, which creates a new User object and stores it in the MongoDB, has a tendency to create duplicates despite the fact I have #Unique on the loginId field.
Now, I know part of the problem is that I am thinking about things from a JPA/RDBMS perspective, and MongoDB is not a relational DB and thus has a different set of parameters in which to operate with, but I having trouble finding guidance in anything more than a VERY simple sample code.
First, what Spring/Other annotations are available, and more importantly, commonly used when dealing with MongoDB from a Spring-world? Second, when dealing with documents that need to be "uniqued", how does one typically do this? Do you first search on the unique field to ensure it's not already there first, then do the insert? Third, in JPA-land, I could use the annotations #PrePersist and #PreUpdate to do last-minute data manipulation, like MD5-hashing passwords that have been updated or adding/updating a "Last Modified" date just prior to storing. I know this are JPA-isms, but can I still use those, and if not, is there an alternative for use with Spring Data/MongoDB?
I ended up using the #Id annotation on my Entities, which indicates which field is used as the id field. As long as the field is unique, writting subsequent updates will properly replace the existing entity instead of adding a new one.
I ended up creating additional method to check if there exists a data which have a duplicate value to the one we are entering.
If it exists, i return failure mentioning that there exist duplicate value. Otherwise it saves the newly entered value

I don't need/want a key!

I have some views that I want to use EF 4.1 to query. These are specific optimized views that will not have keys to speak of; there will be no deletions, updates, just good ol'e select.
But EF wants a key set on the model. Is there a way to tell EF to move on, there's nothing to worry about?
More Details
The main purpose of this is to query against a set of views that have been optimized by size, query parameters and joins. The underlying tables have their PKs, FKs and so on. It's indexed, statiscized (that a word?) and optimized.
I'd like to have a class like (this is a much smaller and simpler version of what I have...):
public MyObject //this is a view
{
Name{get;set}
Age{get;set;}
TotalPimples{get;set;}
}
and a repository, built off of EF 4.1 CF where I can just
public List<MyObject> GetPimply(int numberOfPimples)
{
return db.MyObjects.Where(d=> d.TotalPimples > numberOfPimples).ToList();
}
I could expose a key, but whats the real purpose of dislaying a 2 or 3 column natural key? That will never be used?
Current Solution
Seeming as their will be no EF CF solution, I have added a complex key to the model and I am exposing it in the model. While this goes "with the grain" on what one expects a "well designed" db model to look like, in this case, IMHO, it added nothing but more logic to the model builder, more bytes over the wire, and extra properties on a class. These will never be used.
There is no way. EF demands unique identification of the record - entity key. That doesn't mean that you must expose any additional column. You can mark all your current properties (or any subset) as a key - that is exactly how EDMX does it when you add database view to the model - it goes through columns and marks all non-nullable and non-computed columns as primary key.
You must be aware of one problem - EF internally uses identity map and entity key is unique identification in this map (each entity key can be associated only with single entity instance). It means that if you are not able to choose unique identification of the record and you load multiple records with the same identification (your defined key) they will all be represented by a single entity instance. Not sure if this can cause you any issues if you don't plan to modify these records.
EF is looking for a unique way to identify records. I am not sure if you can force it to go counter to its nature of desiring something unique about objects.
But, this is an answer to the "show me how to solve my problem the way I want to solve it" question and not actually tackling your core business requirement.
If this is a "I don't want to show the user the key", then don't bind it when you bind the data to your form (web or windows). If this is a "I need to share these items, but don't want to give them the keys" issue, then map or surrogate the objects into an external domain model. Adds a bit of weight to the solution, but allows you to still do the heavy lifting with a drag and drop surface (EF).
The question is what is the business requirement that is pushing you to create a bunch of objects without a unique identifier (key).
One way to do this would be not to use views at all.
Just add the tables to your EF model and let EF create the SQL that you are currently writing by hand.

How to serialize two different sets of fields of an object

I have a some classes which I need to serialize in two different ways: first- "basic" fields, and the second- some other fields.
e.g. a User class which I sometimes need to serialize just the "first name" and "last name" fields, and sometimes I need to serialize the "id" and "email"
fields as well.
The best way I found to do this so far is mark the basic fields with the [DataMember] attribute, and let .NET do the serializing for me, and for the rest
mark them with a customize attribute and do the serialization myself.
This solution proved to be very costly:
I first sirialize the basic attributes (as mentioned, .NET does that for me)
Then I get the property names of the fields marked with the custom attribute (using reflection namespace),
Then I try to get the those fields and their values from the object, and add their serialization to the basic serialization (not very successfully so far).....
Question is:
Is there a better way? preferbly by which .NET will do the rest of the work for me, and if not, at least one by which I don't need to go through all the
object's fields, find the relevant ones and serialize them myself..
Thank you all..
Oren,
Are you having to run these operations 1000x or more per minute? If not, all but the clumsiest of solutions will not be too costly. For exmample, if you need to do it like this, working from 2 objects is probably just fine. if you haven't actually run real timing comparisons, there's a huge chance you're wrong about what's expensive and what isn't.
But if you want to do it like this anyway, here is a solution that will only take 1% more time.
have an object, e.g., Core, for the subset, and Full for the whole thing
in the constructor of Full, instantiate a private instance of Core (composition pattern sort of). This has insignificant overhead.
Full will not have private member variables for the Core members. Full's setters and getters of the core data will refer to the private instance of Core. So no overhead.
Now you have 2 objects to serialize.

Callbacks on entity on created/updated

I would like to know when entities in a certain database table are either created or updated. The application is essentially a CMS, and I need to know when changes are made to the content so that I can reindex them for searches.
I know that the autogenerated LINQ to EF class has overridable methods for when certain fields change, but I need to know when the whole object is created/updated, not just a single field. I tried putting it in OnCreated, only to find that meant OnObjectInitialized and not OnObjectInsertedIntoDBTable xD
I did some searching and came across this link. The "Entity State" section looks like its what I want, but I'm not sure how to use this information. Where do I override those methods?
Or perhaps there is a another/better way?
(I also need to know this for another part of the system, which will send notifications when certain content is changed. I would prefer this code to execute automatically when the insert/update occurs instead of placing it in a controller and hoping hoping I always call that method.)
You need to get ObjectStateEntry(s) from the ObjectStateManager property of the ObjectContect.
var objectStateEntries = this.ObjectStateManager.GetObjectStateEntries();
This entries contain every object state you've pulled down per context and what kind of actions where performed on them.
If you are using EF4 you can override the SaveChanges method to include this functionality. I've used this technique to audit every change that occurs in the database instead of triggers.