These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 posts ] 
Author Message
 Post subject: field access questions...
PostPosted: Fri Jul 20, 2007 2:28 pm 
Newbie

Joined: Thu Jun 28, 2007 5:02 pm
Posts: 12
I was wondering if anyone had any insight on the following questions:

1) Is there any way to allow a field accessor to set a member variable into an interface rather than a class (provided that class implements that interface).

This is something you can do with property accessors as the actual storage into the member variable is handled by the getter/setter in code created by the developer. The .Net framework applys the appropriate cast when nHibernate goes down this path...

If you attempt this with field access, you get an error as nHibernate expects the member to be a class rather than an interface to it. Even when I specify the class in the mapping file (rather than letting nHibernate try to figure it out, as it obviously couldn't do in this scenario), the same problem occurs.

2) Is utilizing a pattern that uses interfaces for members such as this a misuse of nHibernate? (i.e. is there a best practice that says you should allow one to switch between field or property with no problems)

3) Is there any sort of performance difference between utilizing field accessors over property accessors? It seems logically that the field access would be faster because it's not necessarily doing a reflection + call stack type of operation.

Thanks in advance for any assistance someone can provide here.

Dan


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 20, 2007 4:12 pm 
Expert
Expert

Joined: Fri May 13, 2005 11:13 am
Posts: 292
Location: Rochester, NY
Just to clarify, you mean a situation like:
Code:
interface I {
   int ID { get; }
   string Foo { get; set; }
}

class A : I {
   private _id;
   private _foo;

   public int ID { get { return _id;} }
   public string Foo { get { return _foo; }
      set {
         // some code that shouldn't be run by NH...
         _foo = value;
      }
   }
}

<class name="I"...>
   <id name="ID" access="nosetter.lowercase-underscore" >
      <generator class="native"/>
   </id>
   <property name="Foo" access="nosetter.lowercase-underscore" />

   <subclass name="A"/>
</class>


Not that I can help, but I'd be interested in the answer too.

Also, my understanding is that the field access is slower than property access, but I couldn't elucidate the reasons.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 20, 2007 6:38 pm 
Newbie

Joined: Thu Jun 28, 2007 5:02 pm
Posts: 12
Closer to this...

Code:
namespace some.namespace {
interface IClassA {
   int ID { get; }
   string Foo { get; set; }
}

class ClassA : IClassA {
   private int _id;
   private string _foo;

   public int ID { get { return _id;} }
   public string Foo {
      get { return _foo; }
      set { _foo = value;  }
   }
}


class ClassB {
   private int _Id;
   private IClassA _bar;

   public int ID { get { return _Id;} }
   public IClassA Bar {
      get  { return _bar; }
      set  { _bar = value;  }
   }

}

}

Mapper...

<class name="ClassB"...>
   <id name="ID" ...>
      <generator class="native"/>
   </id>
   <many-to-one name="Bar" column="SomeBarID" class="some.namespace.ClassA, some.namespace" cascade="all-delete-orphan" />

</class>



if I reference the property "Bar" as the accessor, it works.
If I reference the field "_bar" it fails (even though you tell nHibernate that the field should be of ClassA, which implements IClassA -- the field's type in the object)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 23, 2007 8:15 am 
Regular
Regular

Joined: Wed Apr 25, 2007 4:18 am
Posts: 51
Location: Belarus, Gomel
Hi MutantNinjaLoungeSinger!

Very interesting question. I'd say it must be ok to use interface in this case, and there must be no problems as you specify real class in mapping... There must be no difference between property and field access. Maybe there is problem with "optimized object loader" - try to turn it off to see if it is the case.

BTW I don't think that NHibernate will do it's work faster if you specify field access - I bet it will go through reflection in any case (AFAIK there is no other way to setup private members), and there is no other way to refer "arbitrary named members" - members whose names and types you (NHibernate to be more clear) don't know at compile-time - restriction of strongly typed language :)

_________________
WBR, Igor


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 24, 2007 5:32 pm 
Expert
Expert

Joined: Fri May 13, 2005 11:13 am
Posts: 292
Location: Rochester, NY
Well, that is different... but that mapping is fishy to begin with. Why do you need to specify the class in the mapping and not the code? Seems like it should be the same in both places. Also, cascade='all-delete-orphan' isn't legal on a many-to-one. It doesn't make any sense.


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 07, 2008 2:05 pm 
Newbie

Joined: Thu Jun 28, 2007 5:02 pm
Posts: 12
ugh! I almost forgot about this topic (over a year old, so forgive my extremely late responses)

Quote:
Well, that is different... but that mapping is fishy to begin with. Why do you need to specify the class in the mapping and not the code?

Because it is a requirement by our coding standards to not tightly couple nHibernate (or any other ORM solution) to our domain objects. Leaking nHibernate-specific attributes into assemblies that aren't devoted to managing persistence would be strongly scrutinized during code review.

Quote:
cascade='all-delete-orphan' isn't legal on a many-to-one. It doesn't make any sense.


You are probably correct there. I admittedly do not know how all the various cascade switches work for each context.

Our mapping files are created through a proprietary code-smith based code-generator. I agree that the code-generation would need to be tweaked to deal with that legality. Especially if guards are put in place in a future version that will cause nHibernate to fail.

However, the code executes despite that, so the implication is that the illegal attribute is ignored entirely and falling back to some legal one.

Or... Are you suggesting that the illegal cascade attribute is actually affecting the way lazy-loading is handled? [/quote]


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 07, 2008 10:55 pm 
Regular
Regular

Joined: Wed Oct 25, 2006 10:51 pm
Posts: 71
MutantNinjaLoungeSinger wrote:
ugh! I almost forgot about this topic Because it is a requirement by our coding standards to not tightly couple nHibernate (or any other ORM solution) to our domain objects.


You're not coupling nHibernate to your domain objects by using Mapping.Attributes. The Mapping.Attributes are metadata and it's not even in the NHibernate assembly.
Xml is just a trick around the same problem, except that it's not refactorable or typesafe (the trade-off)

Quote:
Our mapping files are created through a proprietary code-smith based code-generator

An interesting double-standard! No dependencies on ORM's but a dependency on a 3rd party code generator! Our standards are the opposite - no 3rd party code generators.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 11, 2008 1:37 pm 
Newbie

Joined: Thu Jun 28, 2007 5:02 pm
Posts: 12
Quote:
You're not coupling nHibernate to your domain objects by using Mapping.Attributes. The Mapping.Attributes are metadata and it's not even in the NHibernate assembly.
Xml is just a trick around the same problem, except that it's not refactorable or typesafe (the trade-off)

I'm using NH1.2, and the only documentation I'm finding on mapping attributes as metadata is via the add-in "NHibernate.Mapping.Attributes". Unless I'm misunderstanding and there is some way to decorate the classes without introducing this assembly, it's not something we're interested in doing.

While I understand that this isn't the NHibernate assembly itself, for all intents and purposes, it could just as well be. Decorating the domain objects with attributes from this assembly tightly couples it to a very NHibernate-specific implementation and breaks cohesion. Should I want to move to some other ORM strategy, I'd want to and have to remove all of the attributes before I could even de-reference the mapping assembly. As long as they're mapped as metadata, I'd have to always deploy this assembly with my domain layer. Even if I'm doing something that doesn't require persistence, such as unit testing. In fact, I wager the reason this is a separate assembly to begin with is to minimize the number of nHibernate-centric dependency demands on your domain objects if one were to decide to go this route.

But to be clear, we're not following the "Active Record" pattern here, which is what that attribute tool is for. I'm getting the impression from your (miopic) insight that you've never developed an architecture outside of that methodology. And if that truly is the case, you're really in no position to criticize our standards as you've obviously never been in situation where it's been important for the persistence layer to remain agile. I realize the "Active Record" pattern is a good pattern for most applications. But then, most applications have a solid investment and commitment to the type of persistence they're going to leverage. This application is not one of them.

We have looked at and continue to look at other ORM, and object-relational database solutions. So, our persistence layer is a moving target. There has even been a lot of talk of different versions of the software that would be identical except for the persistence.

To be fair, your points about type safety and refactoring are valid. Those aren't really huge issues for us because we use code generation to help in maintaining the code integrity. If that wasn't the case, I can definitely see where the benefits you describe lie.

Your "suggestion" is noted, however. Should things stabilize and there's been a settlement on NHibernate, it becomes a much more comfortable and pragmatic move, even if it does break some principles of agile design and bleeds persistence-specific implementations where it technically doesn't belong.


Quote:
An interesting double-standard! No dependencies on ORM's but a dependency on a 3rd party code generator! Our standards are the opposite - no 3rd party code generators.

I didn't say it was 3rd party, but I see how you might have interpretted it that way, so I apologize for not being clear enough.

Proprietary = we own it. Or rather, we coded all of the code generation scripts in-house.

Even if we didn't own it, code-smith is a multi-purpose scripting engine, so editing a 3rd party script wouldn't be difficult or out of the question.

From your statement, I'm not sure you understand what a dependency is. We (and arguably anyone else using a code generator) are not dependent on code generation. If we felt we had a lot of time on our hands and we were craving some really mind-numbing work, we could hand code all of our classes, interfaces, hbm and table-creation files.

We opt to leverage code generation to save time, enforce consistency and eliminate human error.

The reason I mentioned it at all was because there was a question about why the cascading flag was set up the way it was. Since it was generated that way, I had no real good answer as to why that decision was made (that part of generation was written before I inherited that responsibility). Marcel's comment was helpful, and I've since tweaked the code generator to not do that anymore.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jul 12, 2008 6:31 am 
Regular
Regular

Joined: Wed Oct 25, 2006 10:51 pm
Posts: 71
Quote:
While I understand that this isn't the NHibernate assembly itself, for all intents and purposes, it could just as well be

For all intents and purposes, it's not.
I know where you're coming from, but if you look at the code for the Attributes assembly, it's just a bunch of zero-logic text to basically enable creating the same thing that the embedded XML does. Most of it is generated by a code generator!

Quote:
I'm getting the impression from your (miopic) insight that you've never developed an architecture outside of that methodology.

Let's stick to the point, shall we. Which is "does using attributes couple your domain objects to NHibernate?"

Quote:
even if it does break some principles of agile design and bleeds persistence-specific implementations where it technically doesn't belong.

We just see the role of Attributes as slightly different. You seem to be viewing them as code, while I'm calling them non-code metadata. And I don't believe you can "couple nHibernate to your domain objects" when there's no nHibernate code to be coupled with.

However, if I was switching between ORM's on a whim, I can see you might want to avoid the hassle until you settle.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 13, 2008 5:03 pm 
Newbie

Joined: Thu Jun 28, 2007 5:02 pm
Posts: 12
Quote:
For all intents and purposes, it's not.
I know where you're coming from, but if you look at the code for the Attributes assembly, it's just a bunch of zero-logic text to basically enable creating the same thing that the embedded XML does. Most of it is generated by a code generator!

I understand your point of view. If the attributes were some universally accepted schema for all (or even most) ORM's out there, I'd be less resistant to bloating my domain with attribute decorations that are exclusive to NHibernate.

Quote:
Let's stick to the point, shall we. Which is "does using attributes couple your domain objects to NHibernate?"

Actually, the point of the thread wasn't even this subject. But I digress. I apologize for the bite. You seem reasonable to understand there are other points of view out there for software design.

Quote:
We just see the role of Attributes as slightly different. You seem to be viewing them as code, while I'm calling them non-code metadata. And I don't believe you can "couple nHibernate to your domain objects" when there's no nHibernate code to be coupled with.


If attributes were done in .Net differently, I'd agree with your view of them. However, custom attributes are implemented through code (inherited from System.Attribute or something like that if I recall) even if the client code treats it as meta-data. The dependency on the NHibernate attribute assembly and the garbage it leaves around if I go to a different ORM is my gripe with utilizing that strategy (which is why I strictly use the XML files as they can live in my persistence layer)


Our argument here brings up an interesting point though. If there was a universally accepted attribute layer that all ORM's adopted, it would probably eliminate the need for XML-type implementations altogether. Regardless if it was NHibernate, Entity Framework, Db4o or whatever other solutions are out there. While some may argue that ANY ORM-specific decorations shouldn't bleed persistence into the domain, a pragmatic developer in that world would see the benefit of it if it were utilized by more than one specific framework.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.