Doctrine 2 : Best way to manage many-to-many associations - orm

Doctrine2 ORM have 2 technical ways to handle many-to-many associations :
1/ For a "simple" relation between 2 entities, and without additionnal attribute :
Use #ManyToMany associations between entities
In this case, the link table is used directly, without an association entity
2/ When link table introduces extra fields or more than 2 entities :
Use an association class, ie an "real" entity to map the link table
In this case, the direct ManyToMany association is replaced by OneToMany/ManyToOne associations between the participating entities
These 2 implementations are quite different.
But, in some cases, future business requirements can quickly need to change simple associations, by adding extra fields for example.
In this case, we must replace direct ManyToMany associations in existing entities by the second implementation and refactor affected code.
So, is it a good way to always use association entities to handle all
ManyToMany associations ?
Otherwise, what are the best practices for
choosing the good implementation and handle these kind of domain
model evolutions ?

If you have a good reason to belief that in the near future you will have extra properties on your ManyToMany join table then it's a good idea to make an entity out of precaution. If not then it's better to use the normal ManyToMany relationship. Then when a change is needed you can update your schema along with your code. If you try to follow the Single responsibility principle then you can avoid refactoring large amounts of code.

Related

How to link four tables avoiding N-ary association

I have those four tables in database :
USER
id
PERMISSION
id
OBJECT
id
CONTEXT
id
Now the problem is that I want to link them to say that a user has one or many permissions on one or many objects depending of a context.. It looks simple but I can't find a way to avoid n-ary association..
Hope someone will be kind enough helping me to solve this problem.
Thanks in advance.
You may be looking for something like a WEAK ENTITY
Basically, a weak entity is a database entity which doesn't make sense on its own, but needs one (or more) foreign keys to assume a proper identity and a meaning.
This means that you're moving from an N-ary relationship to N binary relationships.
One possible approach is this: let's say that we call this weak entity Rules
Rules(id, user_id, permission_id, object_id, context_id /*other columns*/);
each of your strong entities has a relationship with the rules table. I don't like a lot this approach, but for small datasets it may work pretty well.
As a general note, though, I suggest you to think a bit more about your database model: are you absolutely, positively sure that all these 4 entities have a so strong relationship together? For example, does "Context" has influence on users, objects and permissions or just on permissions? Does an object exists at the same time across multiple contexts, or it makes sense to bind an object inside a specific context (the same concept of a variable scope)?

Any real use for table-per-concrete-class with implicit polymorphism?

If mapping inheritance using table per concrete class, while mapping concrete classes simply just as any other class (without union-subclass), NHibernate allows same PKs across subclasses. For example if you have BillingDetails and subclasses CreditCard and BankAccount, requesting all BillingDetails will get you all records from both tables, which can in turn have duplicate primary keys, which can be problematic due to not valid business identity of those objects. This of course is not the case with guids and such, but what about cases of plain identity or sequence id generators?
Simply, the question is, is there any real use of this scenarion of duplicate id keys when requesting polymorphic query like that? Could these duplicate ids make problems for NHibernate when handling entities internally?
Implicit polymorphism is necessary when mapping legacy models where the tables do not share a common key.
There are no problems with getting a list of BillingDetails with CreditCard and BankAccount instances sharing the same Id, because NH knows they are unrelated (and they are treated as related only for the purposes of querying, by running one query for each mapped subclass)
You should not use it for greenfield development.

Unidirectional parent-child association not null

I have a class structure which is akin to a PurchaseOrder (parent) and PurchaseOrderLine (child) pattern, where the order lines will only be saved to the DB by saving the parent PurchaseOrder and will only ever be accessed via the parent too.
The DB has PurchaseOrderLine.PurchaseOrder set to not permit null values.
It seems from searching through the web that it is not possible to have a uni-directional association from PurchaseOrder via an IList property without having to have a property on the line pointing back when the child has a NOT NULL constraint for its PurchaseOrder column.
Is this really the case? It seems like one of the most basic things one would want to do with an ORM, I find it difficult to accept that a product as mature as NHibernate cannot handle such a basic scenario.
No it's not the case. Please see the example provided in the answer to this question: When to use inverse=false on NHibernate / Hibernate OneToMany relationships?
Well, it may be the case that you can't have unidirectional one-to-many relationship defined only on one side, but I'll argue with your statement that this is "one of the most basic things one would want to do with an ORM".
One of the most basic things would be to have unidirectional one-to-many defined only on many side - as it is natural for RDBM tables. And ORMs (despite the common misconception) are not intended (or able) to fully abstract domain model from underlying data source. Even if in some cases they can, the database side suffers from select N+1 problems or very ineffective queries.
Defining one-to-many at one side makes an impression that i.e. counting the collection is cheap. It is the case with plain object graphs, but not with NHibernate entities, as reading collection causes (at least one) call to the database. Eager fetching from one side is also not able to properly use database join mechanism in the way it's intended to be used (opposite to eager fetch from many side).
Even if I don't agree with a lot of arguments, I think it is useful to read some of the articles saying that "ORM is an anti-pattern", like this one. They helped me to leverage the way I think about ORMs and make me think about ORMs as a compromise between two not matching paradigms, but not the way to hide one behind another.
This can now be achieved in NH3 using the Not.KeyNullable()
this.HasMany(x => x.Actions)
.Access.BackingField()
.KeyColumn("[Application]")
.Not.KeyNullable()
.Cascade.AllDeleteOrphan();

Fluent NHibernate auto mapping - how to create a many-to-many relationship table?

just wondered if anyone know if there is a way to crate a Many-to-Many relationship table automatically using some attribute? without creating the table, or mapping a class to become that relation table.
If i add the attribute [ManyToMany(3,Class="DeploymentListUsers")] i get an error that this class isn't mapped to the DB.
NHibernate.MappingException: An
association from the table Users
refers to an unmapped class:
I don't want to define the class myself, nor creating the table in the DB before hand.
it's seems possible in JAVA, does fluent NHibernate is a fully implemented version of hibernate and JPA annotations?
http://www.hiberbook.com/HiberBookWeb/learn.jsp?tutorial=19mappingmanytomanyrelationships
Thanks,
Itay
If you specify a class, you must make sure it exists too. NHibernate will not create a class for you. If however, your many-to-many table only contains a foreign key to your deployments table and a foreign key to your users table, you won't need such a class. You will only need a separate many-to-many mapping class if you want to store additional facts about the relation.
As far as I can tell, in your situation you just need to create the many-to-many table (you could use NHibernate's SchemaExport() to generate the CREATE TABLE statement so there's some automation there) and tell NHibernate how to map to it. Unlike you, I don't use mapping attributes so I don't know how to do map using them but it is probably very simple.
NHibernate now supports JPA (called NPersistence or NPA for the .NET platform) including JPA annotations.
It is the best way to specify relations and have your code portable for other vendors as well.
check it out:
www.npersistence.com
My answer to a similar question might help you out: https://stackoverflow.com/a/12198533/185200
I ended up extending the many-to-many automapping step to support properties decorated with a custom attribute.

Nhibernate: Make Many-To-Many Relationship to Map as One-To-One

I have two items A and B, which have a uni directional one-to-one relationship. (A has one B)
In the database these are represented by ATable and BTable, and they are linked together by ABTable. (From the database setup it appears there is a many-to-many relationship but there is not, it was done this way for normalization reasons).
The problem is due to this setup, I have only been able to get NHibernate to map this as a many-to-many relationship between the entities. Is there anyway of making the entities have a one-to-one relationship?
The best I could think of is to leave its has a many to many relationship, and then have two properties on the A entity one that returns a List of B, which would satisfy the mapping and a second non-mapped property that would get the first B from the list, to satisfy my application. - but this seems un-eligant.
Are you sure you mean a one-to-one? I've had so many people ask for one-to-one's when they really mean many-to-one's.
Anyway, short of changing your schema, the easiest thing is what you suggested; however, to make it a little cleaner, you can make the collections private so you're only exposing the two properties that fetch the first item. You can see the various methods in Fluent NHibernate for mapping private properties on the wiki.
You might try combining the join-table with one-to-one mappings in various ways. A join-table mapping permits a single class to be persisted across more than one table which have a one-to-one relationship.