Also note the reason why i got to this situation. We did not start our modelling by creating the DB tables and mapping first and try to fit our domain model around it.
Instead, we create our domain-model first and all the domain code and the UI. Then finally try to make NH mapping to fit to the system, and finally generate the DB structure. So it's not like we are strongly against having int as the identity of our entity, we have no problem with it in general. It's just we have *already* modelled the entity with User object as its identity (instead of an integer), everything is already in place, and we were assuming that it would be quite straightforward for NH to map this id as an association. On Mon, Jan 10, 2011 at 3:07 PM, Hendry Luk <[email protected]> wrote: > I forgot to mention that I dont have any association between user and > user.Profile. And by the way, UserProfile is hypothetical. In my specific > domain case, the traversal is unidirectional from the other side. > > I think you misunderstood me. I did read your post, and more importantly I > did *not* say session.Add(new UserProfile(user)) was impossible. If you > continue on a bit further into the sentence, you'll find the actual > question, which is how to identify UserProfile using its associated User > (i.e. session.Get<UserProfile>(user)), instead of a simple arbitrary > integer. Afterall, UserId is its PK, it makes sense to refer it by User, > rather than int. > The best way I could find is to implement it using > session.Get<UserProfile>(new UserProfile(user)) with composite-id. > > I also read your post, and I'm very well familiar with both PK association > and unique FK association in one-to-one mapping. But I dont understand how > can that information help me in having association in my identity (instead > of literal int values)? The only way I knew to have any association in your > identity is by using composite-id, or am I wrong? Could you elaborate how I > can achieve this using either PK or uniqueFK one-to-one? > > Did i miss anything? Thanks for your time replying. > > > On Mon, Jan 10, 2011 at 11:39 AM, José F. Romaniello < > [email protected]> wrote: > >> There isn't any artificial id on a one-to-one by pk. If you have the user, >> and you want his profile you simply do: "user.Profile". >> >> If you have to go to a profile's repository to get the profile, that is >> *unnatural*. >> If you have a composite id with a single column, that is unnatural. >> If you have a many-to-one (profile to user), but you can't have many >> profiles, that is unnatural. >> If you think you need an artificial id, that is because you didn't read my >> message here nor in the blog post. I said nhibernate supports two kind of >> one-to-one scenarios, and you have one scenario where the relationship is in >> the PK. >> >> session.Add(new UserProfile(user)) <- is perfectly possible, and i said so >> in my blog post... Again i think you didn't read it. >> >> 2011/1/9 Hendry Luk <[email protected]> >> >>> Which brings me to this question: >>> Is there any way to have association as your primary key? >>> >>> E.g. something that allows you to say session.Add(new UserProfile(user)), >>> and session.Get<UserProfile>(user)? >>> >>> Cheers >>> >>> >>> On Mon, Jan 10, 2011 at 11:02 AM, Hendry Luk <[email protected]>wrote: >>> >>>> ## Errata... >>>> >>>> I didnt use one-to-one because I wanted to identify my UserProfile by >>>> its User. One-to-one mapping in NH requires me to have an artificial >>>> integer >>>> to identify my UserProfile entity. It's just unnatural for the rest of >>>> my code. For example, my repository would therefore have to use int as >>>> its TKey. (e.g.. userProfileRepository.Get(user.Id), as well as all other >>>> methods that work on Id). >>>> >>>> The more natural way to approach this from my domain-centric view is for >>>> UserProfile to be identified by User (instead of by an obscure integer), >>>> which was the first thing I attempted to model, by placing an association >>>> as >>>> the Id of my entity. >>>> It seemed to be a very sensible and easy thing to do. >>>> >>>> On the DB side, I simply place an FK on my PK (one-to-one). >>>> On model-side, I simply have a "User user" property as my Id. >>>> On the NH side, it seemed that composite-id would be what I had to use. >>>> Wasn't quite successful. >>>> >>>> Now that I find that there's no clean way to map an association as your >>>> entity ID in NHibernate, I think I might have to revert back to one-to-one, >>>> but I'll have to refactor the rest of my code to work with my UserProfile >>>> entity using integer values. >>>> We do our domain modelling using a model-first approach, and try to get >>>> NH to work out the mapping to fit the model, rather than modelling the >>>> domain to fit NH mapping. That's how I got to this problem, and hence the >>>> need to refactor the code if I'm to revert back to using integer in order >>>> to >>>> have so-called "cleaner" NH mapping (using one-to-one). Might be easier to >>>> stick with composite-id and change my code into >>>> session.Get<UserProfile>(new >>>> UserProfile(user)); >>>> >>>> Having said that, crashing during the logging doesnt seem ideal to me. >>>> Logging module shouldn't really cause an exception. >>>> >>>> On Sat, Jan 8, 2011 at 8:12 PM, José F. Romaniello < >>>> [email protected]> wrote: >>>> >>>>> Session.Get for composite ids work as you said (with a full entity). >>>>> There is another approach for composite ids, using a class for the id, >>>>> a component, in that case get expect an instance of the component >>>>> type. >>>>> >>>>> Where did you read about an anonymous type? >>>>> >>>>> You are wrong about the composite id and you are wrong about using a >>>>> many to one. You DONT have many profiles for a user, you have only >>>>> one, thus it is a one-to-one association (by pk) perfectly supported >>>>> by nhibernate. >>>>> >>>>> Composite ids are composite, it is not right having one column. >>>>> >>>>> 2011/1/8, Hendry Luk <[email protected]>: >>>>> > That's because composite-id is the only way to make many-to-one >>>>> association >>>>> > on your ID. There's no other way. >>>>> > You are allowed to have one or more properties as your composite-id. >>>>> So one >>>>> > property is completely a valid mapping. >>>>> > >>>>> > What's invalid here is apparently the way I retrieve the instance, it >>>>> had a >>>>> > semantic error. The correct way to get the object is: >>>>> > session.Get<UserProfile>(new UserProfile{Id = user}); >>>>> > >>>>> > Unfortunately the following code doesnt work either (it fails during >>>>> the >>>>> > logging attempt): >>>>> > session.Get<UserProfile>(new {Id = user}); >>>>> > >>>>> > You have to construct an actual fullblown UserProfile entity to >>>>> represent >>>>> > your ID solely for querying purpose. >>>>> > >>>>> > Similarly, if you have 2 properties under your composite-id, you >>>>> can't do >>>>> > this either: >>>>> > session.Get<UserProfile>(new {Id1 = a, id2 = b}); >>>>> > That will throw an error during logging too. You always have to >>>>> instantiate >>>>> > your entity. >>>>> > I havent' had a chance to investigate if this error is just a logging >>>>> > problem during the debug-mode, and whether it will actually work just >>>>> fine >>>>> > in the production-mode (non-debug). >>>>> > >>>>> > Cheers, and so yes I have managed to get that working by >>>>> instantiating a >>>>> > dummy instance of my entity for every call to GetById, which is not >>>>> optimal >>>>> > but it works. >>>>> > >>>>> > On Fri, Jan 7, 2011 at 10:24 PM, José F. Romaniello >>>>> > <[email protected]>wrote: >>>>> > >>>>> >> I didn't go further on reading this message after i saw the mapping. >>>>> >> Composite-id means composite-id, multiples columns are part of the >>>>> PK and >>>>> >> you have *only one.* >>>>> >> The weird part of this, is that I'm sure you have read somewhere how >>>>> bad >>>>> >> are composite ids, however you have a pretty common case of >>>>> one-to-one by >>>>> >> primary key, that is very well supported by nhbiernate and you are >>>>> trying >>>>> >> to >>>>> >> map it as a composite id. >>>>> >> >>>>> >> Read the section of one-to-one mapping, >>>>> >> >>>>> http://nhforge.org/doc/nh/en/index.html#mapping-declaration-onetoone >>>>> >> you need to use <generator class="foreign" on UserProfile id as >>>>> described >>>>> >> there. >>>>> >> >>>>> >> >>>>> >> 2011/1/7 Hendry Luk <[email protected]> >>>>> >> >>>>> >>> Hello, >>>>> >>> How does one go about reporting a new bug in NH jira? >>>>> >>> I encountered the following issue. >>>>> >>> >>>>> >>> <?xml version="1.0" encoding="utf-8" ?> >>>>> >>> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" >>>>> >>> assembly="MyDomain" >>>>> >>> namespace="MyDomain.Model"> >>>>> >>> >>>>> >>> <class name="UserProfile"> >>>>> >>> >>>>> >>> <composite-id > >>>>> >>> <key-many-to-one name="Id" column="UserId" class="User" /> >>>>> >>> </composite-id> >>>>> >>> >>>>> >>> </class> >>>>> >>> </hibernate-mapping> >>>>> >>> >>>>> >>> session.Get<UserProfile>(user); >>>>> >>> >>>>> >>> During debug-mode, that will throw an InvalidCastException from >>>>> >>> ComponentType.ToLoggableString() method. It's fine during non >>>>> debug-mode. >>>>> >>> >>>>> >>> The cause of that error, as I tracked down, is due to an attempt to >>>>> get a >>>>> >>> string description from entity's ID (User object) by calling >>>>> >>> ComponentType.ToLoggableString(). >>>>> >>> Since we specify neither the property-name nor the class attribute >>>>> in the >>>>> >>> <composite-id> element, nhibernate mistakenly uses >>>>> EmbeddedComponentType >>>>> >>> of >>>>> >>> UserProfile class (instead of User class) in its attempt to >>>>> >>> GuessEntityMode >>>>> >>> of our User object. This will obviously fail, and the logger >>>>> decides to >>>>> >>> throw exception on this situation (it should at least resort to >>>>> other >>>>> >>> method.. afterall its sole purpose is just to print the string >>>>> >>> representation of the Id object). >>>>> >>> >>>>> >>> There's no appropriate workaround that I can think of that wouldn't >>>>> >>> compromise what I want to achieve. I can't specify class name in >>>>> the >>>>> >>> <composite-id> element because NH will (inappropriately) complaint >>>>> that >>>>> >>> this >>>>> >>> entity doesnt have an ID (because I set the class without the >>>>> >>> property-name). And obviously I can't specify the property-name >>>>> because I >>>>> >>> want to have "many-to-one"ed complex type as my ID. >>>>> >>> >>>>> >>> I strongly believe this is a bug that needs to be fixed, and make >>>>> the >>>>> >>> logging less intrusive. This issue has been raiseed in java's >>>>> Hibernate >>>>> >>> before ( >>>>> >>> http://opensource.atlassian.com/projects/hibernate/browse/HHH-3148 >>>>> ) >>>>> >>> >>>>> >>> Some ways to fix this that I can think of: not relying on tuplizer >>>>> for >>>>> >>> logging at all, or may be resort to other way to produce the >>>>> logging >>>>> >>> string >>>>> >>> in situations when no tuplizer is found (rather than throwing an >>>>> >>> exception). >>>>> >>> >>>>> >>> Cheers >>>>> >>> >>>>> >>> -- >>>>> >>> 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]> >>>>> <nhusers%[email protected]<nhusers%[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]<nhusers%[email protected]> >>>>> <nhusers%[email protected]<nhusers%[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]<nhusers%[email protected]> >>>>> . >>>>> > For more options, visit this group at >>>>> > http://groups.google.com/group/nhusers?hl=en. >>>>> > >>>>> > >>>>> >>>>> -- >>>>> Enviado desde mi dispositivo móvil >>>>> >>>>> -- >>>>> 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. >>>>> >>>>> >>>> >>> -- >>> 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. >>> >> >> -- >> 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. >> > > -- 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.
