Symfony2 Denormalize XML data to Doctrine Entities With Relations - serialization

I'm using Symfony2 and Doctrine 2.0. I'm trying to read data from an XML feed and map this to new or existing entities in the database. When data in the XML feed changes I need update existing entities, but when the data is added I should create new entities.
In my entity classes I'm using the following denormalize methods to map the XML data to the entity's properties:
function denormalize(SerializerInterface $serializer, $data, $format = null)
(Defined in Symfony\Component\Serializer\Serializer called inside my Entity classes)
The docs for this method state that "It is important to understand that the denormalize() call should denormalize recursively all child objects of the implementor." and this is what I'm trying to do. However entities should not know about the EntityManager so how do I check, inside the denormalize() method if a related/child entity already exists or not?
Kind regards,
Matthew

It is indeed a bad idea to call the EntityManager in an entity (and, as far as I know, outside a controller).
I've never faced that problem, but if I were you I'd try to denormalize in one of your controllers, or if it really bothers you, in a service that you call in a controller, and to which you give your EntityManager (here again, best do it in the controller itself, or simply send your objects to the service so it can denormalize the xml "into" the objects).
Best would be to write a controller that works no matter the entity given.
Hope that helps!

I think my problem was in my approach and not really my code!!
Originally, each time I found an entity represented in the XML I would check (using the EntityManager) to see if it was new or existing BEFORE denormalizing it. I took this route because there is duplication in the XML and I was worried about creating duplicate entities in the EntityManager. Cheacking to see if an entity already existed meant I could update the existing entity rather than create a duplicate. Now with my new approach every time I find an entity represented in the XML I denormailze it into a new entity. Of course this creates duplication in the EntityManager, just as there is in the XML, but this can be handled later, hopefully..!
So far this is proving to be a better solution, although I am experiencing some issues when trying to merge the duplicate entities in the EntityManager using $em->merge(); and cascade={"persist", "merge"}. I've posted a new question about this here: Doctrine 2.1 - Relation Lost After ManyToMany Cascade Merge - Symfony2
Matthew

Related

Few questions related to Atlas HiveMetastoreBridge code

I was going through HiveMetastoreBridge code in Apache Atlas and encountered few doubts.Pardon me if these questions are very naive.
HiveMetastoreBridge code
Why are we clearing relationships in findEntity method?
What does add referred entity does exactly in the background ? To be clear in toTableEntity method we are adding ObjectId of related entites as attributes as well calling addReferredEntity method of AtlasEntity.
In registerInstance method why are we creating references from first entity to other referred entities in else if statement. When will multiple entities be created and why will the first have reference to others?
In importTable method why after creating AtlasEntity processInst we are again creating AtlasEntitiesWithExtInfo createTableProcess and adding process entity and path entity to it? Why not Table entity too?

mapping entities with relations backed by obfuscated fields with NHibernate

And here goes yet another question on NHibernate.
This one most likely doesn't have a desired answer, but still - let's give it a try.
I'm currently putting all the efforts into mapping a domain model onto the database using NHibernate. This domain model comes from a framework which is heavily obfuscated. (Not that I have worked a lot with obfuscated code before, but this one in most of the places can be translated neither by Reflector, nor by Resharper.)
Everything went more or less fine until I faced an entity with a required many-to-one relationship represented by a property with no setter with obfuscated backed field.
Is it possible to reference this obfuscated field somehow? A very special IPropertyAccessor?
If not, how can I load a fully constructed entity? The only option to inject a related object is by using a constructor that accepts it. But at the time of instantiating of an entity being loaded, neither IInstantiator nor IInterceptor has any data of it apart from the key. Any other extension points that suit my need?
To allow NHibernate to access your field instead of property you can use this in your mappings:
access="field"

Automatic migration with abstract entities

I have a model that has an abstract entity with two entities that inherit from this abstract entity.
When I try doing automatic migration I get an error about there being no mapping model so I created a mapping model and then get errors about multiple validation errors.
Looking closely at the mapping model that has been generated neither of the entities have any attributes from their parent included in the mapping model, one of which is not optional and seems to be generating the error during migration.
Is it possible to use automatic migration when abstract entities have been used ?
If not then I am busy creating a custom migration class using the following simple statements to migrate each attribute.
[newObject setValue:[sInstance valueForKey:#"name"] forKey:#"name"];
How do I migrate relationships ? Can I use the same approach for relationships shown below ?
[newObject setValue:[sInstance valueForKey:#"parent"] forKey:#"parent"];
[newObject setValue:[sInstance valueForKey:#"children"] forKey:#"children"];
Thanks.
OK I found my problem - DO NOT make any small changes to your original data model because things will fail !!!
I have mistakenly made a change to the original data model, once I have figured out what this was and reset it things started working.
To overcome the abstract entity problem I had to create a CustomMigrationClass which copies each attribute and relationship across. All works nicely now.

Fluent Nhibernate Domain Driven Design

Hi Im curious about how DDD is really implemented using Fluent Nhibernate. for example I have an entity class called User and another class called UserProfile, as far as Im concerned UserProfile is not an entity class but a value type, and should not realy have an identity as such if not associated with a User entity. Now to implement practically the user profile will ideally be stored in a database table called UserProfile and I cant see how I can get away from having a unique Id for this table. I am also using FluentNhibernate as an ORM and I beleive THE UserProfile class needs to have an Id in order to be mapped correctly. So what happens to the concept of values types, aggregate root etc, Is it really possible to implement a true DDD with fluent Nhibernate or is it just that my understanding of DDD is poor. All I have really seen is a lot of theory about the whole thing, but I have not seen a project that really has true DDD using NHibernate. I am a bit confused now, any help is appreciated
Update
Okay after a bit of reading up I understand that repositores are used to manage Aggregate roots, clears up some of the issues but ultimately the userprofile class is not an aggregare root, so should I still give it a Id? it obviously needs one in the database table so Im assuming the class needs an Id as well. But does this not go against the principle of DDD? what is the way around this?
It will need an Id to be supported by your ORM (NHibernate), and that's perfectly fine. The distinction between Entities and Value Types is their concepts of identity and lifetime. Having an Id field is simply an implementation detail here.

Extended properties with Entity Framework or NHibernate

Is there are an easy way to store some of entitie's properties in a column as a bulk, as XML or something? Querieng by those properties of course is not an option, but it still'd be valuble to be able to extend data model without database migration.
For NHibernate you can use dynamic-component
http://nhibernate.info/doc/nh/en/index.html#components-dynamic
or
using the dictionary as a name-value list
nhforge.org/doc/nh/en/index.html#collections-mapping
or even Duck-Typing
http://fabiomaulo.blogspot.com/2009/07/duck-typing-with-nhibernate.html
As far as I know you are not able to do this directly with NHibernate, but you could implement a private property which composes and decomposes your fields to a string and map to that property instead of mapping your fields directly.
But I am not sure if this really something you should do in the first place. Usually requirements tend to come up during development and lifetime of an application and once you are going to need one of the fields - even if you now think you will never need to query for that field - you will have a hard time. Adding a column to a table of an existing database is not much of a deal and you still need to update the xml for every tuple in the table, so I really think it is better to store only one field in a column.
Best Regards,
Oliver Hanappi
Not in NHibernate. I don't know about Entity framework.
You still need a database migration to store the XML field, so it won't prevent you having to do a database schema update when you find this feature in Entity framework or some other framework.
Yes, you can do this in NHibernate using a serializable object and an IUserType implementation. This link describes how to create an IUserType implementation for a SQL Server XML field and this link describes how to build on that to serialize an object to an XML field.
You could try converting the xml to a string before you store it in the database.
The Entity Framework does not support
a native-XML data type. This means
that when an entity is mapped to a
table with an XML column, the
equivalent entity property for the XML
column is a string. Objects can be
disconnected and serialized as XML.
For more information, see Serializing
Objects (Entity Framework).
http://msdn.microsoft.com/en-us/library/cc716791.aspx