<many-to-one> and access setting
Hi
According to http://nhforge.org/doc/nh/en/index.html#mapping-declaration-manytoone, NH supports the access setting, but it's ignored i Fluent NHibernate.
I have:
References(FluentNHibernateExtensions.Field("Subscription"))
.Access.PascalCaseField(Prefix.Underscore)
.Cascade.None();
(Dont't mind the Field method. It does the same as Reveal.Property, but with fields)
The output is:
<many-to-one cascade="none" class="..." name="Subscription">
<column name="Subscription_id" />
</many-to-one>
Is this going to be supported?
Ken
2 Posted by Ryan on 11 Nov, 2010 02:54 PM
Same issue here, and it's driving me friggin nuts. I absolutely need this behavior to work. 7 months and no response from the fluent team? What gives?
3 Posted by ryan on 11 Nov, 2010 02:59 PM
My problem is actually with a mapping.References, and FYI, I can't create a new ticket. Page is not found on post.
Hello,
I'm having an issue with setting Reference properties through their fields. It seems to simply ignore the Access settings on references, and helps itself to my setter. This is a bit of an issue.
mapping.References(m => m.ToppingGroup).Access.CameCaseField(Prefix.Underscore);
No effect. Still goes through the setter. Any advice?
Thanks,
Ryan
Support Staff 4 Posted by James Gregory on 11 Nov, 2010 05:31 PM
"What gives?" is that the bugs that people shout about the most are the ones that get fixed first. No shouting, no fixing until we run out of issues people are shouting about. This question may have been asked 7 months ago, but nobody has complained about it since and not even the original poster prompted us again. I admit it's not very good that we didn't respond, but where's the prerogative when the OP hasn't checked back in 7 months?
As for your actual issue, I'll investigate it ASAP.
Support Staff 5 Posted by James Gregory on 11 Nov, 2010 08:11 PM
Right, I've just tried to reproduce your issue on our latest
v1.x
build and failed. My overrides are correctly setting theAccess
, and it's reaching the mapping.What version are you running? Have you tried upgrading?
6 Posted by Ryan on 11 Nov, 2010 08:37 PM
I tried upgrading to build 695, and got an Errors in Named Queries exception when spinning up the session factory. I'm using the current 1.x build from the main download link.
I've dug a little deeper into the original issue, and it's only using the setter on derived classes.
So, If I have two classes (both are concrete entity types), Product, and DerivedProduct where DerivedProduct inherits Product, the Reference properties are being set through the setters in the DerivedProduct only. In Product, it correctly uses the field accessor.
If I add the same override for DerivedProduct, I get an InvalidOperationException because it tries to add a property that's already added.
Support Staff 7 Posted by James Gregory on 11 Nov, 2010 08:59 PM
Could you export your mappings and attach them here?
There's an WriteMappingsTo method on AutoMap that you should be able to use.
On Thu, Nov 11, 2010 at 8:39 PM, Ryan <
***@tenderapp.com<tender%***@tenderapp.com>
> wrote:
8 Posted by Ryan on 11 Nov, 2010 09:17 PM
Here's the mapping for relevant part of the inheritance heirarchy. MenuItem>Product>ProductOverride
You can see that in all of the reference properties in ProductOverride that are inherited from Product are missing the access attribute. It seems to be there for all of the simple value type properties. I haven't overridden any of the behaviors of the collection properties, but I can add them if you'd like to see if they exhibit the same issue.
Thanks,
Ryan
Support Staff 9 Posted by James Gregory on 11 Nov, 2010 10:04 PM
Well, something's not working right because your many-to-one's are being
mapped in Product and ProductOverride, that shouldn't happen. What overrides
have you got applied that produced this mapping?
As an aside, this would be much easier using a convention rather than
overriding everything.
On Thu, Nov 11, 2010 at 9:19 PM, Ryan <
***@tenderapp.com<tender%***@tenderapp.com>
> wrote:
10 Posted by Ryan on 11 Nov, 2010 10:18 PM
It is almost entirely handled through conventions. I have an override for one property on ProductOverride that doesn't exist on Product and doesn't follow the normal conventions, and about 5 properties on Product that don't follow the conventions. The overrides modify behavior of collections and map properties to columns whose names don't match. The only thing I'm having issues with are these reference properties on the entities that derive from other concrete entities.
Support Staff 11 Posted by James Gregory on 12 Nov, 2010 10:09 AM
Found it!
Sorry, I mistakenly thought you were using overrides for everything and thus my tests didn't show anything failing.
If you want to know the technical reasons for it not working, read on (otherwise skip the next few paragraphs):
I'm not in a position to commit a fix right now, but I'll be able to do it later tonight. You've got 3 options until then:
GetAccessStrategyForReadOnlyProperty(Member)
method in yourIAutomappingConfiguration
and change it to return what you need. Conventions still wouldn't be able to overwrite the value from this method until I apply the fix, but at least it would get you going again.If you want to apply the fix yourself:
v1.x
"stable pre-release" source package) or from our v1.x branch on github.ReferenceStep
class, which is insrc\FluentNHibernate\Automapping\Steps
That's it, rebuild and you should be fine.
12 Posted by Ryan on 15 Nov, 2010 01:40 PM
Perhaps I'm doing something wrong, or perhaps we have a misunderstanding. I have overridden the GetAccessStrategyForREadOnlyProperty as suggested, and it had no effect. This is not a read only property, though. It is just a property that I need to bypass the setter logic during hydration of the object.
Here is my override:
public override FluentNHibernate.Mapping.Access GetAccessStrategyForReadOnlyProperty(FluentNHibernate.Member member)
{
}
Support Staff 13 Posted by James Gregory on 15 Nov, 2010 02:17 PM
No matter, the fix is in. You should be able to update to the latest 1.x binary.
14 Posted by Ryan on 15 Nov, 2010 02:51 PM
OK, now with the latest build (1.2.0.691), I get the "Errors in named queries" exception when the session factory spins up. Nothing has changed in the named queries that I have set up. Do you know what has changed in that part of the code that I need to account for?
Then, upon removing the line that loads the mappings for the named queries, and executing a unit test involving one of the entities in question, it still uses the setter for the property in question. Again, it's not a problem in Product, just ProductOverride. It does go through the field in Product, although, that isn't even really necessary.
15 Posted by Ryan on 16 Nov, 2010 01:16 PM
Am I downloading the wrong build? I know it wasn't the highest build number, but it was marked as the latest. The fix doesn't seem to change anything, aside from breaking things in other parts of the application.
Support Staff 16 Posted by James Gregory on 16 Nov, 2010 01:54 PM
Well in that case you're going to have to give me a more comprehensive example, because one of us is doing something wrong.
17 Posted by Ryan on 16 Nov, 2010 03:13 PM
OK, I'm attaching a sample project with a test to generate the mappings and a test that shows the stored procedure mapping errors. Let me know what you think.
18 Posted by Ryan on 16 Nov, 2010 03:18 PM
HMM, don't know what happened to the file. Does it not like zip files?
Support Staff 19 Posted by James Gregory on 16 Nov, 2010 06:40 PM
Got it the second time, thanks.
On Tue, Nov 16, 2010 at 3:18 PM, Ryan <
***@tenderapp.com<tender%***@tenderapp.com>
> wrote:
20 Posted by Ryan on 18 Nov, 2010 01:34 PM
Any new info?
Support Staff 21 Posted by James Gregory on 18 Nov, 2010 11:24 PM
The issue you're having with the named query is because of a breaking change since our last release, to work around it you need to remove the multiple calls to
Mappings
in yourFluent.Configuration
and just use one. We'll fix that before the next release.After changing that, I'm not entirely sure I can replicate your issue. Could you check again after trying the above suggestion? If it still doesn't work, could you attach a schema? Using SchemaExport on my end doesn't seem to be working very well.
22 Posted by Ryan on 19 Nov, 2010 02:10 PM
That fixed the query problems, thank you.
The issue with it mapping the references differently in subclasses of persistent classes still exists. If you look at the mapping for ConcreteClass.OutsideHeirarchy, and ConcreteClassOverride.OutsideHeirarchy, you'll see what I mean.
I never went as far as to actually generate the schema or try to work with the entities. I was only interested in looking at the mappings that were generated. I have fixed the issues in the attached project, and you should be able to generate the schema now if you'd like.
Thanks for all the help.
--Ryan
23 Posted by Ryan on 22 Nov, 2010 08:28 PM
Any new info? Are you having any better luck with my example?
24 Posted by Ryan on 22 Nov, 2010 09:10 PM
OK, I've been trying some different things, and debugging, and I've noticed something I think is strange, and might help to point you to the bug. I'm not that familiar with the fluent code, but I have figured out what it happening.
For reference properties, it only seems to be looking for mapping overrides or conventions on properties that are declared on the class in question. So, if it is declared in a superclass, it never inspects that property.
The same does not seem to be true for HasMany, or HasManyToMany. They both seem to be inspecting properties regardless of where they are declared. I will start hunting with this in mind.
25 Posted by Ryan on 22 Nov, 2010 09:27 PM
Sorry, I totally dropped the ball here. My references were somehow all pointing back to the older version of the assembly. Everything works great now. Sorry for being a pest. Keep up the excellent work.
Thanks,
Ryan