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.
Related
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.
I am new to Core Data modeling, and I am having a hard time understanding how one-to-many relationships work.
I have a parent entity called Task, which can have several instances of Comment entity. I modeled it like this: on Comments, a relationship to Task called task with the Task entity a destination. On Task, a relationship called comments, with Comment as its destination, and both relationships are each others inverse.
Not defining an inverse results in either warnings or error messages. While modeling this way works, I've noticed that once I create a second comment for a given Task, the first is replaced (one-to-one relationship).
What would be the correct way to tell the Core Data Model that this relationship allows many comments in one Task?
Also, since CoreData seems to manage primary keys on its own, how would I create an NSPredicate to retrieve all comments for a given Task?
Thanks for any suggestions!
First of all you need to set the plural option in the Task entity, select it in your .xdatamodeled and select the relationship property of Task entity to comments you should be able to see this
there is a plural option be sure to check that out. You must recreate your NSManagedObject if your using generated classes and also if your using sqlite store you must delete and rebuild so it will not complain about the new schema not being the same with the old one.
To check if you have a one to many relationship your Task entity should have a property called comments which is a class type of NSSet not Comments.
If you want to retrieve all comments for a given task you need to iterate the NSSet(comments) property of that task.
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();
I have an entity Library that mains two lists of Books. It is important that the library maintain these two lists of books. On my Library entity I have a relationship thats one to many from each list to my Book entity. Likewise, Book has a relationship "library". I'm having some problems with my data being erased from the database and I read that I should be setting up inverse relationships to help with data integrity. In this case however, a Book would want to be able to set up an inverse relationship with each list on my Library entity. How can I accomplish this?
My naive first thought is to implement relationships for both lists. So a book has a relationship "libraryForList1" and "libraryForList2" so that it can have an inverse for each relationship. I'll never have to actually reference these properties because according to the Core Data spec, if I add a book to one of the library lists, it automatically takes care of setting the library as that books owner.
Your "naive first thought" is essentially correct: If your Library entity has two one-to-many relationships with Books (for clarity let's call the relationships ownedBooks and borrowedBooks), then your Book entity should have to-one inverse relationships (owningLibrary and borrowingLibrary) and then Core Data will make your life easier.
You may also need to think about the delete rules on these relationships: If a Book is deleted for some reason, the delete rules for the owningLibrary and borrowingLibrary would likely be Nullify – that is, both libraries would remove the Book from their lists. Deleting a Library that still has Books seems like a bad idea, so maybe the delete rule for ownedBooks and borrowedBooks should be Deny: A Library can't be deleted until the books are all accounted for (and removed from the Library).
It's been a while since I've had to work with relational databases (I've been avoiding it as much as I can in my personal projects, and at work we use an object database) so I'm fairly sure this is the correct way, but I wanted to make sure.
When modeling a relational database from an existing object hierarchy it is generally the case that non-primitive child properties should go in their own tables with a reference to the ID of the parent object (table-row thingy). It seems a little backwards from an OO standpoint (and obviously I realize that relational is way different from OO) but I guess it's the only way to represent one-to-many relationships (which feels like it should be more accurately described as many-to-one as the one parent doesn't reference the many children, it's many child entries that reference the one parent)
Yes.
In one-to-many relationships, the child points to the parent.
In many-to-many relationships (and one-to-many relationships with attributes, ternary relationships, etc.), you have relation tables.
In one-to-one relationships, you either merge the tables, or either entity can point to the other.
While this is by no means the only way, it certainly is the only sane way of representing relationships. All other methods I can think of break normalization (in fact, I can't even think of another 1NF method, let alone 3NF).