Skip to content

NH-3667 & NH-3102 Dictionary mapping-by-code improvements #311

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 21, 2014
Merged

NH-3667 & NH-3102 Dictionary mapping-by-code improvements #311

merged 1 commit into from
Sep 21, 2014

Conversation

rjperes
Copy link
Member

@rjperes rjperes commented Aug 31, 2014

@hazzik
Copy link
Member

hazzik commented Sep 1, 2014

«Stop, little pot»

@rjperes
Copy link
Member Author

rjperes commented Sep 1, 2014

Needs something else... Like this!

@rjperes
Copy link
Member Author

rjperes commented Sep 1, 2014

Fixed

@rjperes
Copy link
Member Author

rjperes commented Sep 1, 2014

Hooray!

@oskarb oskarb changed the title NH-3667 & NH-3102 NH-3667 & NH-3102 Dictionary mapping-by-code improvements Sep 2, 2014
@@ -1280,7 +1280,8 @@ protected virtual ICollectionElementRelationMapper DetermineCollectionElementRel
{
return new OneToManyRelationMapper(propertyPath, ownerType, collectionElementType, modelInspector, customizerHolder, this);
}
if (modelInspector.IsManyToMany(property))
//NH-3667 & NH-3102
if ((modelInspector.IsManyToMany(property)) && ((property.GetPropertyOrFieldType().GetGenericArguments().Length < 2) || ((property.GetPropertyOrFieldType().GetGenericArguments().Length > 1) && (modelInspector.IsEntity(property.GetPropertyOrFieldType().GetGenericArguments()[1])))))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For readability, can we get that split on several lines please? Use a nested if-statement if it helps readability.

@rjperes
Copy link
Member Author

rjperes commented Sep 2, 2014

Alex, you are a hard man to please! :-)

{
var args = property.GetPropertyOrFieldType().GetGenericArguments();

if ((args.Length < 2) || (args.Length > 1))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably I'm stupid, but I don't understand that condition:(

@rjperes
Copy link
Member Author

rjperes commented Sep 2, 2014

You're not stupid! :-)
The problem was: ModelMapper was considering a dictionary to always be a many-to-many. That, however, is not the case in two situations: when we have values of elements or components instead of entities.
If the collection is not generic, we can't really say anything about it, so we go with the original behavior. When we have entities as values, we also go for the original behavior. In any other case, we know that we do not have a many-to-many.

@hazzik
Copy link
Member

hazzik commented Sep 2, 2014

I'm asking only about args.Length < 2 || args.Length > 1

@rjperes
Copy link
Member Author

rjperes commented Sep 3, 2014

If we have a generic collection with a single generic parameter (eg, IList) or if we have one with two (eg, IDictionary<TKey, TValue>)...

@AlexeiScherbakov
Copy link

(args.Length < 2 || args.Length > 1) is true always

0 - true ( args.Length < 2 is true)
1 - true ( args.Length < 2 is true)
2 - true (args.Length > 1 is true)
And so on

@rjperes
Copy link
Member Author

rjperes commented Sep 5, 2014

Alexei:
It's a new technique called LNDP - Late Night Driven Programming!
Of course you and Alex are right. The point is: if we have a generic collection with a single generic parameter, check that it is an entity. If the collection has two, check the second. I will update the pull request. What's more important is, this fixes some reported problems.

@rjperes
Copy link
Member Author

rjperes commented Sep 5, 2014

I cleaned up the code. Can you try rebuilding?

@oskarb
Copy link
Member

oskarb commented Sep 6, 2014

I cannot tell - is the change made in the correct place or is it the implementation of modelInspector.IsManyToMany() that should really change? There is such a large number of classes there, with very little documentation, so I must admit I'm confused.

@rjperes
Copy link
Member Author

rjperes commented Sep 6, 2014

The two errors from ExplicitColumnNameIsAlwaysMapped are caused because class Bar is not mapped. The test would also fail if we were to open a session factory - see for yourself.

@rjperes
Copy link
Member Author

rjperes commented Sep 6, 2014

The problem is that whenever we call IMapKeyRelation.ManyToMany to register an entity key the property is registered as a many to many in class AbstractExplicitlyDeclaredModel. So method ModelMapper.DetermineCollectionElementRelationType assumes that the collection value is an entity, but sometimes it is an element or a component. My solution fixes this, but there are other possibilities. I think this is an important issue.

@hazzik
Copy link
Member

hazzik commented Sep 19, 2014

Hi Ricardo, could you please squash all this stuff? Or alternatively - could you add me to your fork?

@rjperes
Copy link
Member Author

rjperes commented Sep 19, 2014

Alex: what do you mean?

@hazzik
Copy link
Member

hazzik commented Sep 19, 2014

What question is confusing you?

@rjperes
Copy link
Member Author

rjperes commented Sep 19, 2014

Well, the "add me to your fork" is easy, but what do you mean by "squash all this stuff"?

@rjperes
Copy link
Member Author

rjperes commented Sep 19, 2014

Right, I added you, because I'm on an ipad far away from my machine. Will only be back by sunday.

@hazzik
Copy link
Member

hazzik commented Sep 20, 2014

Ok, thanks

@oskarb
Copy link
Member

oskarb commented Sep 20, 2014

So this is ready to go in then?

To be honest it looks a bit like a hack to me, but the test case seems solid and the code is localized so I don't think it's too much of a problem. The related DetermineMapKeyRelationType() does contain the comment "Perhaps we have to change IModelInspector with IsDictionaryKeyManyToMany(member), IsDictionaryKeyComponent(member) and so on", which might be a hint that really MapKeyManyToManyCustomizer should do something slightly different than just explicitDeclarationsHolder.AddAsManyToManyRelation(propertyPath.LocalMember);.

I havent't studied the code close enough to tell really... so this patch LGTM.

oskarb added a commit that referenced this pull request Sep 21, 2014
NH-3667 & NH-3102 Dictionary mapping-by-code improvements
@oskarb oskarb merged commit 4ec16a2 into nhibernate:master Sep 21, 2014
@rjperes rjperes mentioned this pull request Sep 21, 2014
@hazzik hazzik deleted the NH-3667 branch September 21, 2014 11:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants