mapping with field access

129 views
Skip to first unread message

Fost andy

unread,
Jul 30, 2009, 11:57:04 AM7/30/09
to Fluent NHibernate
Hi,

I feel a bit silly for asking this but how do I map a field directly?

In traditional hibernate I might want something like:

<property name="ss" type="String" access="field"/>

How do I achieve this in fluent?

I tried Map(x => x.ss).Access.AsField();

but this throws
System.InvalidCastException: Unable to cast object of type
'System.Reflection.RtFieldInfo' to type
'System.Reflection.PropertyInfo'.

On a whim I tried .SetAttribute("access", "field") but got the same
error.

thanks.

Mikael Henriksson

unread,
Jul 30, 2009, 1:07:16 PM7/30/09
to fluent-n...@googlegroups.com
I do Access.AsField that way successfully for my Version columns...

2009/7/30 Fost andy <fost...@gmail.com>

James Gregory

unread,
Jul 30, 2009, 1:10:43 PM7/30/09
to fluent-n...@googlegroups.com
We only support using properties currently, all the expression based methods expect PropertyInfo's not FieldInfo's.

Any reason you're using a field over an auto-property?

Fost andy

unread,
Jul 31, 2009, 9:59:39 AM7/31/09
to Fluent NHibernate
Not a good one :) I was using someone else's code which had private
fields, no property accessors, and was using a inner class classmap to
access them. I have since changed the fields to auto-properties.

Thanks for clarifying.

On Jul 31, 3:10 am, James Gregory <jagregory....@gmail.com> wrote:
> We
> only support using properties currently, all the expression based
> methods expect PropertyInfo's not FieldInfo's.
> Any reason you're using a field over an auto-property?
>
> On Thu, Jul 30, 2009 at 6:07 PM, Mikael Henriksson <mik...@zoolutions.se>wrote:
>
> > I do Access.AsField that way successfully for my Version columns...
>
> > 2009/7/30 Fost andy <fosta...@gmail.com>

sbohlen

unread,
Jul 31, 2009, 11:30:53 AM7/31/09
to Fluent NHibernate
Just FYI for some perspective, many people (like me!) prefer field
mappings to property mappings for at least two (and probably more)
reasons:

1) we want to bypass (any) side-effects of setters/getters when
hydrating/persisting entities; yes, setters/getters with side-effects
are *generally* a code-smell but there are legitimate use-cases that I
don't want persistence-concerns to inadvertently trigger

2) property mappings lead to needlessly verbose public surface areas
on entities; not everything an entity needs from the database to do
its work is a good idea to expose to the outside consumer of that
entity (field-mappings more easily support the entity-as-domain-object
instead of the entity-as-DTO pattern that property-mappings encourage)

If we are voting (and FWIW I'm not sure we are!), I personally would
like support for field-level mappings ASAP; for me its a major
concession in the design of my domain model for persistence to only
support property mappings and FNH needs influencing the shape of my
domain objects feels like tail-wags-dog in many cases.

Just my $0.02

-Steve B.

On Jul 30, 1:10 pm, James Gregory <jagregory....@gmail.com> wrote:
> We
> only support using properties currently, all the expression based
> methods expect PropertyInfo's not FieldInfo's.
> Any reason you're using a field over an auto-property?
>
> On Thu, Jul 30, 2009 at 6:07 PM, Mikael Henriksson <mik...@zoolutions.se>wrote:
>
>
>
> > I do Access.AsField that way successfully for my Version columns...
>
> > 2009/7/30 Fost andy <fosta...@gmail.com>
>
> >> Hi,
>
> >> I feel a bit silly for asking this but how do I map a field directly?
>
> >> In traditional hibernate I might want something like:
>
> >> <property name="ss" type="String" access="field"/>
>
> >> How do I achieve this in fluent?
>
> >> I tried Map(x => x.ss).Access.AsField();
>
> >> but this throws
> >> System.InvalidCastException: Unable to cast object of type
> >> 'System.Reflection.RtFieldInfo' to type
> >> 'System.Reflection.PropertyInfo'.
>
> >> On a whim I tried .SetAttribute("access", "field") but got the same
> >> error.
>
> >> thanks.- Hide quoted text -
>
> - Show quoted text -

James Gregory

unread,
Jul 31, 2009, 1:13:20 PM7/31/09
to fluent-n...@googlegroups.com
We do have full intention of supporting as much of fields as we can, but it's not a high priority right now (getting the release out with what everyone's already been using for the past year is). There's always going to be trouble around private fields that don't have a public getter, because we can't access them via a lambda, but we can always provide string based alternatives (however much that undoes one of the key strengths of FNH); for example the Reveal functionality does allow you to use private properties currently, if you're willing to use strings.

The whole issue is that our entire public interface is based on PropertyInfo, it has been from day one. I don't think much consideration was given to fields in the beginning and as such they've kind-of fallen to the wayside. It's clear what we have to do (replace all instances of PropertyInfo with some higher-level abstraction that could be a PropertyInfo or FieldInfo (or MethodInfo!) under the hood), it's just a matter of getting the time and resources to do it.

There isn't any voting happening because we're already decided that we will support fields, we were a long time ago :)

As always, patches are welcome ;)

Paul Batum

unread,
Jul 31, 2009, 8:27:54 PM7/31/09
to fluent-n...@googlegroups.com
Stephen,

I'd just like to point out that private auto properties

a) Cannot have any logic in getters and setters
b) Do not appear in the public interface of your domain objects.

i.e. Neither of your objections apply when replacing your private fields with private auto properties.

Of course, to map to those private autoproperties you need to either give up some compile time safety (by using Reveal as James mentioned, or mapping to a public property and then using an access modifier), or sacrifice "domain purity" and nest your mappings inside your entities.

Paul Batum

sbohlen

unread,
Aug 1, 2009, 7:41:48 AM8/1/09
to Fluent NHibernate
Paul:

Good points -- I may be inadvertently conflating PUBLIC autoproperties
with PRIVATE autoproperties (and also PROPERTIES with AUTOPROPERTIES)
here. Honestly it never occured to me to have private properties
(again, auto or not) on my objects even though there's clearly no
compiler-rule that says I can't so I think when I read 'property' in
the above thread my mind immediately just inferred 'public'
accessibility for them.

Since my usual architectural approach to using NH typically involves
mapping fields rather than properties (auto or not), obviously none of
my properties *can* be auto-properties since auto-properties (sadly)
don't have predicatably-named backing stores that I could map to using
'traditional' non-FNH approaches (e.g., XML).

Given James' reply, I can see TWO issues that would seemingly need to
be overcome here: one being that everything would of course need to
have an option to be expressed in terms of FieldInfo rather than
PropertyInfo, and the other being how do you get the lamba-reflection-
trick to work against private members. The FieldInfo v PropertyInfo
issue is straightforward, but can you point me to a reference (blog
post, whatever) that demonstrates what mapping to a private property
would look like (using this 'Reveal' option) --? I would like to
explore what this looks like as a semi-viable alternative to having to
expose all data-bound values in my objects as public properties even
though I agree with James' post that this renders much of the benefit
of FNH impotent.

Unfortunately, the only non-string-dependent way that I am aware of to
access private members via anything similar to the lamda-reflection-
hack is to do code-gen to create a parallel class hierarchy, each
parallel class full of properties that correlate exactly to both the
public and private members of your objects so that you can express the
private members in lamba statements. This is obviously significantly
less than idea b/c you're just moving the responsibility for keeping
things 'logically consistent' from string-literals to whatever your
code-gen executable is, but I have seen this approach generally work
leveraging the somewhat flakey integration of VS and the T4 templating
engine. Obviously this approach is counter to (or at least different
from) what you're trying to accomplish with FNH, but I have seen it
work.

Thanks again for the suggestions; in the end it may just be that the
overall architectural approach that FNH is taking (using the lamda-
reflection-hack to avoid string-literals) is simply incompatible with
my general approach of mapping to private fields in objects (square
peg, meet round hole <g>).

-Steve B.

On Jul 31, 8:27 pm, Paul Batum <paul.ba...@gmail.com> wrote:
> Stephen,
>
> I'd just like to point out that private auto properties
>
> a) Cannot have any logic in getters and setters
> b) Do not appear in the public interface of your domain objects.
>
> i.e. Neither of your objections apply when replacing your private fields
> with private auto properties.
>
> Of course, to map to those private autoproperties you need to either give up
> some compile time safety (by using Reveal as James mentioned, or mapping to
> a public property and then using an access modifier), or sacrifice "domain
> purity" and nest your mappings inside your entities.
>
> Paul Batum
>
> On Sat, Aug 1, 2009 at 3:13 AM, James Gregory <jagregory....@gmail.com>wrote:
>
>
>
> > We do have full intention of supporting as much of fields as we can, but
> > it's not a high priority right now (getting the release out with what
> > everyone's already been using for the past year is). There's always going to
> > be trouble around private fields that don't have a public getter, because we
> > can't access them via a lambda, but we can always provide string based
> > alternatives (however much that undoes one of the key strengths of FNH); for
> > example the Reveal functionality does allow you to use private properties
> > currently, if you're willing to use strings.
>
> > The whole issue is that our entire public interface is based on
> > PropertyInfo, it has been from day one. I don't think much consideration was
> > given to fields in the beginning and as such they've kind-of fallen to the
> > wayside. It's clear what we have to do (replace all instances of PropertyInfo with some higher-level abstraction that could be a PropertyInfo or FieldInfo (or MethodInfo!) under the hood), it's just a matter of getting the time and resources to do it.
>
> > There isn't any voting happening because we're already decided that we will
> > support fields, we were a long time ago :)
>
> > As always, patches are welcome ;)
>
> >> > - Show quoted text -- Hide quoted text -

James Gregory

unread,
Aug 1, 2009, 8:22:25 AM8/1/09
to fluent-n...@googlegroups.com
Since my usual architectural approach to using NH typically involves mapping fields rather than properties (auto or not), obviously none of my properties *can* be auto-properties since auto-properties (sadly) don't have predicatably-named backing stores that I could map to using 'traditional' non-FNH approaches (e.g., XML).

You sure about that? If FNH can do it, NH can do it... AFAIK you just map a private autoproperty the same as a regular public property, no need to specify any access strategy.

You can find info about Reveal at the bottom of this wiki page.

The fact is, fluent isn't going to fit with everybody's style; I wouldn't expect anyone to change their design to use FNH, just as I wouldn't expect anyone to change to use NH. If your design is compatible, then that's where FNH can be of use, if it isn't then there's not much use trying to mash one into the other.

Fields will be supported, but there's always going to be some compromise around inaccessible ones.

sbohlen

unread,
Aug 1, 2009, 12:00:20 PM8/1/09
to Fluent NHibernate
James:

I get it now (I must be a little thick, I guess). You're suggesting
to use a private auto-property as a 'stand-in' for the 'role' of a
field and then map directly to the private autoproperty using FNH...?

Yes, I do think this approach would work; it just requires a sort of
mental shift (on my part) about the use of properties; in this
approach where I would (usually) use a private field, I should instead
use a private autoproperty. Makes sense, and the (slight) overhead of
accessing the private autoproperty vs a private field in my object
model should be near-completely imperceptible (unless doing something
inane like accessing it 1M times in a tight loop <g>).

Thanks for the info on 'Reveal'; that was very helpful. The 'nested-
class' approach delineated in that section of the wiki is basically
accomplishing the same thing as I was hinting at in my prior post
using code-gen techniques at compile-time to create strongly-typed
field-wrapping-properties for persisted entities; the code-gen
approach typically involves declaring the 'hand-written class' and the
'code-generated class' using the 'partial' keyword and the nested
class is code-gen-ed by the template and merged into the 'hand-
written' class at compile-time. You don't get design-time
intellisense support for mapping statements until *after* a first
compile (to fire off the template), but you also needn't maintain
these nested classes by hand either.

Obviously there are pros and cons to all of these strategies, but they
all accomplish somewhat the same thing: (semi-) automatic strongly-
typed access to private fields in persisted classes in lambda
expressions.

I completely agree that in my case FNH may very well not suit my
'typical' implementation pattern for some of the ways that I prefer to
use NH and I'm not so much suggesting that it change in any way to
meet my needs but am more just trying to explore the relative pros and
cons of how well (or not) it aligns with my usual usage patterns, of
course.

Thanks for all the info and I will continue to explore all of this in
greater detail.

-Steve B.


On Aug 1, 8:22 am, James Gregory <jagregory....@gmail.com> wrote:
> > Since my usual architectural approach to using NH typically involves mapping
> > fields rather than properties (auto or not), obviously none of my properties
> > *can* be auto-properties since auto-properties (sadly) don't have
> > predicatably-named backing stores that I could map to using 'traditional'
> > non-FNH approaches (e.g., XML).
>
> You sure about that? If FNH can do it, NH can do it... AFAIK you just map a
> private autoproperty the same as a regular public property, no need to
> specify any access strategy.
>
> You can find info about Reveal at the bottom of this wiki
> page<http://wiki.fluentnhibernate.org/show/StandardMappingPrivateProperties>
> .

Berryl Hesh

unread,
Aug 2, 2009, 5:48:45 PM8/2/09
to Fluent NHibernate
Hi Steve.

How about the "Fall of Fluent NHibernate" for your next major video
production? Kind of just rolls off the tongue, doesn't it??

Seriously, good to see you having a hard look at FNH!

Berryl
> ...
>
> read more »

Paul Batum

unread,
Aug 2, 2009, 6:50:36 PM8/2/09
to fluent-n...@googlegroups.com
How about "Autumn of Fluent NHibernate". The other title could be misunderstood... :)

Berryl Hesh

unread,
Aug 2, 2009, 7:51:38 PM8/2/09
to Fluent NHibernate
you may be right about that one..."Fluently For the Fall"? Oh well, at
least the timing is good with the coming release and all.

On Aug 2, 3:50 pm, Paul Batum <paul.ba...@gmail.com> wrote:
> How about "Autumn of Fluent NHibernate". The other title could be
> misunderstood... :)
>
> ...
>
> read more »
Reply all
Reply to author
Forward
0 new messages