Saving a doctrine2 entity to cache to speed up the page load - zend-framework

Let's say I have an entity called Product and this entity is loaded every time user hits the product information page. Usually I'd save the object in Zend_Cache (memcache) for an hour to avoid hitting the db for each request but as far as I understand that's not possible with Doctrine2 entities because of the Proxy objects.
So my question is, how can I avoid loading the same entity from the database for each request?
[EDIT]
I tried using Doctrine Cache like this
$categoryService = App_Service_Container::getService('\App\Service\Category');
$cache = $categoryService->getEm()->getConfiguration()->getResultCacheImpl();
$apple = $cache->fetch('apple');
But I get the following error
Warning: require(App/Entity/Proxy/_CG_/App/Entity/Category.php)
[function.require]: failed to open stream: No such file or directory
in /opt/vhosts/app/price/library/Doctrine/Common/ClassLoader.php on
line 163
This is same for Zend Cache as well as you can't serialize the entity because of the Proxy class

You've got several options:
Use Doctrine's built-in result caching
Try just sticking entity in memcache via Zend_Cache. When you pull it out, you may need to merge() the Product back into the EM so proxies can be dereferenced. If you fetch-join any associations you need to display the product info, and you're only doing reads, this shoudl work fine.
Don't cache the entity at all. Cache whatever output you generate instead.
EDIT: If you don't care about the hydration overhead, you're using mysql, and your Products and associated tables don't change very often, you might prefer to just rely on the mySQL query cache. It's a fairly blunt object, but useful enough to mention.

You might want to try implementing __sleep or __wakeup methods for your entity class, as Doctrine 2 has special requirements and limitations concerning serialization/deserialization of entities (which is what happens when storing them in Zend_Cache).
There is this guidance.
General information about limitations including serialization.

I find this extremely strange since i just messed around with this myself and didn't have any issues with the proxy object being stored in the database. So im guessing your configuration is not setup 100% ?
If you find the issue with your configuration then be very aware of what timdev said you MUST merge the object back into the EntityManager else you will have weird bugs down the line.
A fourth solution available for you is also to retrieve the data as an array instead of an object, but then of course you lose all the functionality connected to your module which might not be exactly want you wanted.

It seems to me more like a configuration error. Either Proxies have not been generated or there is something wrong with the proxy directory and namespace.
Depending on your configuration, proxies can be either generated automatically or manually. Does your proxies have been indeed generated under App/Entity/Proxy ? Is this indeed the right directory?
FYI proxies can be manually generated by executing doctrine orm:generate-proxies <dest-dir>

Seconding what timdev says: Doctrine has built-in caching, you want to use it.
I also wonder from your question if you are experiencing any performance issues or if you are a victim of overly eager optimisation.

Related

F# mapping data entities to domain entities; what is meant by "using objects for persistance"?

In my spare time, I'm trying restart my effort to learn F#. I'm doing so by trying to create a simple application that will allow me to analyze my financial transactions.
My first attempt at creating this application failed due to the persistence step. I used SQL and the EntityFramework package, but the latter generated database entities, which I did not want to use throughout my application since they're all mutable (I think..). Instead I had to map these database entities to domain entities. Much manual glue code later it worked....until I found a bug and was forced to replace much of that glue code. That was the tipping point that made me quit.
On SO I found a question describing my situation, e.g. Saving F# types to a database. Mark Seeman suggested that the pain of mapping can be overcome if I'd not use objects for persistence. At work I have recently been introduced to MongoDb, which at least saves me the pain of mapping from database entities to domain entities. These entities all need some ID, and I chose to use an ObjectId from Mongo. Ooops, there comes the deja vu, in order not to have my domain entities being dependent on Mongo, I will once more have to create database and domain entities....as well as the mapping. Bah & Ugh.
In C# I'm used to do such mapping with tools like Automapper, but they don't really work for special F# types. So now I'm wondering what Mark Seeman ment by "using objects for persistance". How is this solved in F#? So far I haven't been able to fine more info on this topic besides the aforementioned question on SO.

Correct way to persist and existing JPA entity in database

In one application I am working on, I found that the JPA objects that are modified are not previouly loaded, I mean;
Instead of doing like this:
getEntityManager().find(Enterprise.class, idEnterprise);
//Some modifying operations
They do like this(and works!):
Enterprise obj = new Enterprise (IdEnterprise);
//Some modifying operations
getEntityManager().persist(obj);
This last solution doesnt load from database the object and it modifies the object correctly.
How is this possible?
Is a good practice? At least you avoid the query that loads from database, right?
Thanks
It depends. If you are writing code from a controller class (or any application code) you shouldn't be worried about jpa stuff, so the second approach is bad and redundant.
If, instead, you are working in infrastructure code, maybe you can manually persist you entities to enable some performance optimization or simply because you want the data to persist even if the transaction fails.
I strongly suspect the second bit of code is someone creating an entity from scratch, but mixing application, domain and infrastructure code in the same method: an extremely evil practice. (Very evil, darth father evil, never do that)

Entity framework and inheritance: NotSupportedException

I'm getting
System.NotSupportedException: All
objects in the EntitySet
'Entities.Message' must have unique
primary keys. However, an instance of
type 'Model.Message' and an instance
of type 'Model.Comment' both have the
same primary key value
but I have no idea what this means.
Using EF4, I have a bunch of entities of type Message. Some of these messages are actually a subtype, Comment, inheritance by table-per-type. Just
DB.Message.First();
will produce the exception. I have other instances of subtyping where I don't experience problems but I can't see any discrepencies. Sometimes, though, the problem goes away if I restart the development server, but not always.
Edit:
I've worked out (should have before) that the problem is a fault of the stored procedure fetching my Messages. The way this is currently set up as that all the fields pertaining to Message is fetched, the Comment table is ignored by the sproc. The context then proceeds to muck this up, probably by fetching those Messages that are also Comments again, as you suggested. How to do this properly is the central issue at hand. I've found some indications to a solution at http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/bb0bb421-ba8e-4b35-b7a7-950901adb602.
As you infer, it looks like the Context is fetching a Comment as a Message (not knowing that it is a comment). Later, you ask for the actual Comment, so the context fetches the Comment. Now you have two object instances in the Context with the same ID - one is a Message and one is a Comment.
It seems that the exception is not being thrown until after both objects have been loaded (ie when you try to access the Message the second time). If you can find a way to remove the Message from Context when the Comment is loaded, this may solve your problem.
Another option might be to use the Table-per-hierarchy model. This results in a bad database design but at the end of the day you have to use what works.
You might be able to avoid the problem by ensuring that the objects are loaded as Comments first. This way, when you ask for the Message, the Context already knows about it.
Also consider using Composition over Inheritance, such that a Message has 0..1 CommentDetails.
The final suggestion is to remove the dependency on the Entity Framework from your Control code, and create a Data Access Layer which references the EF and retrieves your objects. The DAL can turn Entity Framework objects into a different set of Entity objects which are easier to use in code. This approach will produce a lot of code overhead, but may be suitable if you cannot use the Entity Framework to produce an Entity model which represents your Entities in the way you want to work with them.
To summarize, unless MS fix this issue, there is no solution to your problem which does not involve a rethink of your approach. Unfortunately the Entity Framework is not ideal, especially for complex Entity models - you might be better off creating your own DAL and bypassing the EF altogether.
It sounds like you are pulling two records into memory one into message and one into comment.
Possible prblems:
There are two physical messages with the same id
The same message is being pulled up as a message and a comment
The same message is being pulled up twice into the same context
That the problem sometimes goes away when you restart, points to a problem with cleaning up of context. Are you using "using" statements.
Do you have functionality for changing from a message to a comment?
I am not an EF kind of guy (busy working with NHibernate, haven't had time to get up to date with EF yet) so I may be totally wrong here, but could the problem be that the two tables (since you are using inheritance by table-per-type) have primary keys that collide?
If you check the data in both tables, do primary key values collide?

Entity Framework - avoiding another query

I have a requirement to only save data to a table in a database (I don't need to read it)
If the record already exists I want to update it otherwise I will add it.
It usually exists.
My entity context might already hold the object .. if it does I want to find it and use it again without causing it to refresh from the database when I 'find' it
i.e. The context holds a collection of entities (rows of a database) I want to find an entity in the collection and only want the context to go to the database if entity is not in the collection. I don't care about the current values of the entity .. I just want to update them.
Hope this is clear ..... thanks
I may not be quite seeing the question, but I believe your looking for some sort of caching mechanism, I know for work we use devForces IdeaBlade which does the trick, however I believe you can create a simple caching mechanism custom to you needs.
Link
The bits on caching will be helpful, if this doesnt help tell me and I can dig a little deeper.
I believe you need to use GetObjectByKey() instead of using an ObjectQuery I believe an ObjectQuery always hits the backend datastore whatever it may be.
More Info here http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.getobjectbykey.aspx

Entity Framework - Autogeneration vs Manually Creation of Entities

You can refer to this post of mine.
It is not the case that, someone will be able to generate perfect Entities from the database tables every time.
If any entity is not looking perfect, how can I tweak it? And how should I tweak it?
Or should I search for the flaw of relations in the Database, fix it first and then try to generate Entities over and over again until the desired entity is generated?
But it may happen that, I would become unable to figure out the reason of an imperfect entity being generated only looking at the database tables.
You should clarify your requirements: should be everything created automatically from database or you allow hand-made updates or will do it manually (once automatically then only manual updates).
Remember, that from time to time after db structure changes you will have to generate entities again, then you may lost your changes. Consider using partial classes, so some of your code changes could be persistent across automatic generations.
But in your case let's try to figure out how how the MS has prepared the demo database and try to follow the rules. Maybe you would like to read some database design guides?
More details about your environment could help with more precise answer.
We generate the EF model based on the database. When the database changes we refresh the model. This works fine for us.
It is only if you are doing something special that you need to tweek your entities.