Thanks for your reply.

A lot of the frustration has been because of the direction of the advice.
i.e. from a database-to-purist Object model POV. that was further
complicated by perhaps my failure to elaborate on the specific requirements
that RIA brought to the table (which i knew were not that big of a deal, but
something i just had to work around). only after repeated attempts did i
become terse. I had constantly affirmed my understanding that i _didn't
need_ the FK, and was understandably frustrated by the response of no
instead of why not.

anyway ..

In short, cascade settings mean that I MUST *always* act (CUD) on items in
collections through the parent?
-- if my client-side code is optimized NOT to send the entire entity graph
back over the wire to add a single, new Note, in order to save that note to
the database, i MUST re-build that entity graph from either the session or
the database, then save the parent?

in your example:

   parent.addChild(child);             // or
   parent.children.add(child);
   child.Parent = parent;              // for bidirectionality

was it your intention to imply that the method addChild() MIGHT NOT be
setting child.Parent, and might only be adding the child to the collection?
In my experience, and based on what everyone here has already said about
object references not key associations, child.Parent is required to be set.
Or is the rule more like: it either has to be set, or be in a collection of
a parent, and NHib will set it for me? Your 'for bidirectionality' leads me
to believe the rule is not like that (it's optional) -- so why would I get
errors if i DON'T set child.Parent?


----> just FYI :: Here's a very good example of a great clearly-explained
response not being consistent, even though it's very clear. I'm not crazy
for seeing the inconsistency, am I? Without the above being clarified, it's
very hard to move forward from this foundation of understanding. Er, it's
hard for 2 people to move forward toward common understanding with such
uncertainty looming in the shadows.

Nonetheless, I'll keep going. I understand where the disconnection is, I
just need answers to clear them up. :D

-- Perhaps now would be a good time to note that what I suggested
originally, did actually work... That's not to say that I'm out of the
woods, and it's only because i'm doing explicit stuff that I'd like to not
have to do, like build up the entire entity graph just to add a single Note.

in case you're all wondering ... the below mapping works as desired:
public class TicketMap : ClassMap<Ticket>
{ public TicketMap() {
    Not.LazyLoad()
    Table("Tickets")
    Id(x=>x.TicketID).GeneratedBy.Sequence("SEQ_TICKET_ID")

    HasMany<Note>(x=> x.Notes)
    .KeyColumn("TicketID")
    .Cascade.SaveUpdate()
}}
public class NoteMap : ClassMap<Note>
{ public NoteMap() {
    Not.LazyLoad()
    Table("Notes")
    Id(x=>x.NoteID).GeneratedBy.Sequence("SEQ_NOTE_ID")

    HasMany<Note>(x=> x.Notes)
    .KeyColumn("TicketID")
    .Cascade.SaveUpdate()

    Map(x => x.TicketID)
    .Not.Insert()
    .Not.Update()
    .Generated.Always()
}}

In order to map the FK column (TicketID) AND the instance (Ticket), AND ALSO
make it work for both read and write, I was doing it backwards. That is, I
was misunderstanding the *magic* NHib was doing to populate TicketID in my
domain, but then was frustrated that it couldn't save it to the database
(the logs indicated TicketID was resolved, but then oracle was saying
couldn't insert null). I was trying to map Ticket as not-insert/update, and
have NHib map TicketID. I was also originally just trying to save a single
Note by itself with
Session.Save(newNote_WithEverythingTheDatabaseTableNeedsButNoTicketInstance).

-- Perhaps this is the question I should ask more directly: I would like to
be able to save an individual note without populating Ticket or without
building out the entire graph of the parent, BUT ALSO be able to save the
entire entity graph like Session.Save(newTicket_WithNewNotesAlso), because
there are scenarios where I will have that as well. Is that possible?

It should now be clear why I need to understand if setting the note.Ticket
instance is a requirement, and if so, when?

BTW, after all hell broke loose and assuming I ever got this resolved, I was
going to offer $10 to whomever decided to actually help. Of course I
couldn't say that before, but JideO and John Davidson will get it, if that's
good enough , for actually trying to help. Sometimes it pays to not be a
parrot on repeat =)

Thanks

------
Joe Brockhaus
[email protected]
------------


On Mon, Feb 7, 2011 at 7:08 PM, JideO <[email protected]> wrote:

> I think a little empathy for Joe's frustration is in order. Joe I
> think you should appologise to people you would have offended by
> taking out your frustration on them.
>
> I have also been on the receiving end of what initially seem to be
> unhelpful answers but later on when I understood the issues better, I
> find that one of the replies I had been frustrated with already
> contained the answer to my question.
>
> Even at this, there are still some questions I have on nhibernate and
> on other forums where I have given up on getting a direct answer
> saying "this is so and so" or "this was not designed to be used like
> so try using it like so" or even "you idiot, what were you thinking,
> that's not what that means but this is the correct meaning". This
> happens even on paid support forums so its not just the OS community.
> Bottom line is this Joe, when you've written a response in frustration
> take a few deep breaths to think it over before pressing the send
> button.
>
> I'm also learning nhibernate so I may be able to answer your questions
> at a level you'll understand. Sometimes the more experienced guys
> communicate in very condensed language, and unless you already
> understand the solution you may find it difficult understanding their
> explanation.
>
> With regards to the cascade option, from my (limited) experience when
> cascade is used on a class property it specifies what should happen to
> a transient instance of objects referred to by the entity when the
> session is eventually flushed or a transaction committed.
>
> eg
>
> if you have a parent object which has a collection of child objects
> and the child collection is defined with a cascade=save-update. If the
> parent object was retrieved from the db/session and you add a child
> object to the parents collection, when the session is flushed or (the)
> transaction is committed the child object will be saved without having
> to do a session.save on the child object.
>
> void dothis()
> {
>
>    ISession session = .....
>
>    ITransaction t = session.BeginTransaction();
>    var parent = session.Get<Parent>(10);
>    child = new child();
>    parent.addChild(child);             // or
> parent.children.add(child);
>    child.Parent = parent;              // for bidirectionality
>
>    t.Commit();                             // or session.flush();
>                                                 // the child object
> will be inserted although you did not
>                                                 // explicitly save it
> }
>
> If the parent object is also new, you have to call session.save on the
> parent object and all its children reachable by cascaded properties
> will be saved as well.
>
> void saveNewParentAndChildren()
> {
>    var parent = new Parent();
>    var child = new Child();
>    parent.addChild(child);
>    child.Parent = parent;
>
>    var session = .... get your session
>    session.Save(parent);
>    session.Flush();                         // this will insert
> cascaded child objects as well
> }
>
> Another aspect which you seem to be missing is that you are referring
> to TicketID in your object model. This is not what is intended. You
> should not have to deal with the TicketID in your note class instead
> you would be referring to the Ticket object instead.
>
> Instead of having
>
> class Note
> {
>     long TicketID;
>     string Text;
> }
>
> what you should have is
>
> class Note
> {
>     Ticket ticket;
>     string text;
> }
>
> Your mapping is where you would specify the column to be used in the
> Note table to store the ticket's id.
>
> The third thing you seem to have trouble with is this issue of
> managing of the references yourself. If you are connecting object
> together nhibernate does not help you manage the object references on
> newly created connections. i.e. if you have a parent object and want
> to add a child object to it you will need to in YOUR code do
> parent.addChild(child) and child.Parent = parent, if you want a
> bidirectional association.
>
> Does this help.
>
> Jide
>
> On Feb 4, 9:42 pm, Joe Brockhaus <[email protected]> wrote:
> > no one is willing to address this, eh?
> >
> > must be too simple of a problem. but alas, it is not.
> > the behavior I'm seeing is both inconsistent, and routinely unexpected
> given
> > common sense.
> >
> > for more context, please see:
> http://groups.google.com/group/fluent-nhibernate/browse_thread/thread...
> >
> > yes, i'm using Fluent for my mappings.
> > yes, I can get you the HBM if you absolutely need it.
> > yes, i'm confident that my problems are both a consequence of not mapping
> > Fluent correctly, and also correct mappings resulting in unexpected NHib
> > behavior.
> >
> > one such issue that does not seem to differ regardless of how I map my
> > entities:
> > -- Does NHib require me to add entities to the Session in the order in
> which
> > they need to be saved to correctly reference a one-to-many/many-to-one
> > association? For instance, if I have a Ticket instance which has mapped
> an
> > IList<Note> ... I'm seeing that if I add 3 Note instances, which have
> valid
> > Ticket instances references and valid Note.TicketID values, to the
> Session
> > BEFORE adding the Note.Ticket instance, then BeginTransaction().Commit ..
> > NHib fails on insert (Note.TicketID is an invalid FK, oracle error, as
> the
> > TicketID column has a FK constraint). If I add the Ticket first, the save
> > works, but the Note instances in the cache are not updated with the
> TicketID
> > generated in Oracle. The database has correct values, but this means that
> if
> > I Load<Ticket>(ticketID) again, Ticket.Notes(0).TicketID, for instance,
> is
> > still 0 -- the value it had BEFORE the transaction was committed.
> >
> > Thanks for your help ....
> >
> > ------
> > Joe Brockhaus
> > [email protected]
> > ------------
> >
> >
> >
> > On Wed, Feb 2, 2011 at 7:14 PM, fel0niousmonk <[email protected]>
> wrote:
> > > background:
> > > -- the database is Oracle.
> > > -- PKs for both tables (TICKETS, NOTES) are generated by sequences
> > > (SEQ_TICKET_ID, SEQ_NOTE_ID)
> > > -- Silverlight & RIA Services
> >
> > > question:
> > > -- given the following, what should my mapping look like?
> >
> > > public class Ticket
> > > {
> > >   [Key]
> > >   public int TicketID {get;set;}
> >
> > >   [Include]
> > >   [Association("Ticket_Notes",
> > >            "TicketID",
> > >            "TicketID"]
> > >   public IList<Note> Notes = new List<Note>();
> > > }
> > > public class Note
> > > {
> > >   [Key]
> > >   public int NoteID {get;set;}
> >
> > >   [Include]
> > >   [Association("Note_Ticket",
> > >            "TicketID",
> > >            "TicketID",
> > >            IsForeignKey = true)]
> > >   public Ticket Ticket {get;set;}
> > >   public int TicketID {get;set;}
> > > }- Hide quoted text -
> >
> > - Show quoted text -
>
> --
> 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