views:

2722

answers:

7

When you create your mapping files, do you map your properties to fields or properties :

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Foo" namespace="Foo.Bar" >
  <class name="Foo" table="FOOS" batch-size="100">
    [...]
    <property name="FooProperty1" access="field.camelcase" column="FOO_1" type="string" length="50" />
    <property name="FooProperty2" column="FOO_2" type="string" length="50" />
    [...]
  </class>
</hibernate-mapping>

Of course, please explain why :)

Usually, I map to properties, but mapping to fields can enable to put some "logic" in the getters/setters of the properties.

Is it "bad" to map to fields ? Is there a best practice ?

+1  A: 

I map to properties, I haven't come across the situation where I would map to a field... and when I have I augment my B.O. design for the need. I think it allows for better architecture.

Sara Chipps
I'm curious: How do you augment your BO design? My problem in the past has been with business rules or relationships that are enforced in the properties getting in the way of persistence when I map to properties. You can see my previous (bad) solution in the question here: http://stackoverflow.com/questions/2979060/what-classes-should-i-map-against-with-nhibernate
apollodude217
+4  A: 

I map to properties. If I find it necessary, I map the SETTER to a field. (usually via something like "access=field.camelcase").

This lets me have nice looking Queries, e.g. "from People Where FirstName = 'John'" instead of something like "from People Where firstName/_firstName" and also avoid setter logic when hydrating my entities.

Gilligan
I don't understand, can you be more specific ? doesn't the access="field.camelcase" do that automatically ? eg <property name="Foo1" access="field.camelcase" ... /> map to Foo.foo1 ? And you can still query with "from Foo where Foo1 = .." ?
mathieu
yes, that is what I mean. In the example in your question you are actually mapping to a property, and mapping only the setter to the field.
Gilligan
ok got it. thanks!
mathieu
+1  A: 

I map to properties because I use automatic properties.

Except for collections (like sets. Those I map to fields (access="field.camelcase-underscore") because I don't have public properties exposing them, but methods.

Matt Hinze
+2  A: 
Mufasa
A: 

I tend to agree with the answers above. Generally, map to properties for almost everything, then map to fields for collection setters.
The only other place you'd want to map to fields is when you have something:

public class AuditableEntity
{
   /*...*/
   DateTime creationDate = DateTime.Now;
   /*...*/
   public DateTime CreationDate { get { return creationDate; } }
}
David Kemp
+1  A: 

Null Objects

Mapping to fields can be useful if you are implementing the null object pattern if your classes. As this cannot be performed (easily) when mapping to Properties. You end up having to store fake objects in the database.

HQL

I was unsure that with HQL queries you had to change the property names if you were using a field access approach. ie if you had <property name="FirstName" access="field.camelcase" /> I thought you could still write "From Person where FirstName = :name"; as it would use the property name still.

Further discussion on field strategies and Null object can be found here.

Performance

In relation to performance of field vs property on John Chapman's blog It appears there isn't much of an issue in performance with small-midrange result sets.

In summary, each approach has certain perks that may be useful depending on the scenario (field access allows readonly getters, no need for setters, property access works when nothing special is required from your poco and seems to be the defacto approach. etc)

Jafin
A: 

I map directly to fields, which allows me to use the property setters to keep track of a property's dirty state.

quip