One word of warning:

   I am testing a legacy database mapping using optional="true" and I
found that if the legacy app that interacts with the database updates
the joined table to remove the data without deleting the row (for
example, clears out all the fields in the address and sets them to
NULL, leaving only the foreign key in the related table), NHibernate
will have problems with this situation. In particular, it will assume
the row *does not exist* and if you go to save the entity, it will
issue an INSERT instead of an UPDATE.

   I don't know if this problem is easy to fix, but I was planning on
writing a unit test/JIRA for it "soon"... I am pretty sure there is no
easy solution for this, since NHibernate will always issue an outer
join for the related table and won't be able to tell the difference
between missing data and a missing row.

   What I think I need is an optional="maybe" that makes NHibernate
more careful in this situation. ;-) It might have to issue a select
before the update (which I know it can do in some other scenarios...).

Regards,
Mike

On Fri, Dec 3, 2010 at 12:13 PM, David McClelland
<[email protected]> wrote:
> I did figure out how to get use only one SELECT statement by
> incorporating a LEFT JOIN into the query.  I used the optional
> attribute instead of the fetch attribute:
>
> <join table="EntityAddress" optional="true">
>
> So...   now the nicely clean EntityAndPrimaryAddress is returned even
> if there is only an Entity with no corresponding address.
>
> - David
>
>
> On Dec 3, 12:51 pm, Jason Meckley <[email protected]> wrote:
>> you could map the address to a private field and expose those
>> properties on the EntityAndPrimaryAddress object. the public api
>> remains clean. the "ugly code" remain encapsulated within the
>> EntityAndPrimaryAddress object.
>>
>> public class EntityAndPrimaryAddress
>> {
>>     private Address address;
>>
>>         public virtual int EntityId { get; set; }
>>         public virtual int CreatedBy { get; set; }
>>         public virtual DateTime CreatedDate { get; set; }
>>         public virtual int ModifiedBy { get; set; }
>>         public virtual DateTime ModifiedDate { get; set; }
>>         public virtual int UpdateCounter { get; set; }
>>
>>         public virtual bool IsPrimary
>>         {
>>                 get {return address.IsPrimary;}
>>                 set {address.IsPrimary = value;}
>>         }
>>     ... the rest of the properties.
>>
>> }
>>
>> i don't see what other options you have. when working with a legacy
>> database details of the database will spill into the domain. the only
>> way to prevent this is to refactor the database along with the code.
>>
>> something else to consider is why querying with a single select is a
>> problem.
>>
>> On Dec 3, 1:06 pm, Fabio Maulo <[email protected]> wrote:
>>
>>
>>
>>
>>
>>
>>
>> > sure.
>> > but you know... the <join> is only a "licenza poetica" of ORM for legacy DB
>> > not designed following ORM.
>>
>> > When you say that the state of an entity is spanned in two tables it mean
>> > exactly that to have the state of an entity NH have to join (inner) two
>> > tables; there isn't another option, NH have to read all properties.
>> > Perhaps you can try using lazy=true in each property and see what will
>> > happen, perhaps it will work but AFIK we don't have a specific test for 
>> > this
>> > situation.
>>
>> > P.S. ORM= Object Relational *Mapping*
>>
>> > On Fri, Dec 3, 2010 at 2:36 PM, David McClelland 
>> > <[email protected]
>>
>> > > wrote:
>> > > But a <one-to-one> won't give me the nicely-flattened entity that I'm
>> > > interested in:
>>
>> > >    public class EntityAndPrimaryAddress
>> > >    {
>> > >        public virtual int EntityId { get; set; }
>> > >        public virtual int CreatedBy { get; set; }
>> > >        public virtual DateTime CreatedDate { get; set; }
>> > >        public virtual int ModifiedBy { get; set; }
>> > >        public virtual DateTime ModifiedDate { get; set; }
>> > >        public virtual int UpdateCounter { get; set; }
>> > >        public virtual bool IsPrimary { get; set; }
>> > >        public virtual string Name { get; set; }
>> > >        public virtual string Line1 { get; set; }
>> > >        public virtual string Line2 { get; set; }
>> > >        public virtual string City { get; set; }
>> > >        public virtual string State { get; set; }
>> > >        public virtual string PostalCode { get; set; }
>> > >    }
>>
>> > > --
>> > > You received this message because you are subscribed to the Google Groups
>> > > "nhusers" group.
>> > > To post to this group, send email to [email protected].
>> > > To unsubscribe from this group, send email to
>> > > [email protected]<nhusers%[email protected]
>> > >  >
>> > > .
>> > > For more options, visit this group at
>> > >http://groups.google.com/group/nhusers?hl=en.
>>
>> > --
>> > Fabio Maulo
>
> --
> You received this message because you are subscribed to the Google Groups 
> "nhusers" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to 
> [email protected].
> For more options, visit this group at 
> http://groups.google.com/group/nhusers?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en.

Reply via email to