views:

929

answers:

3

So far the association works fine (the User class loads the appropriate UserRoles instance when present), but when creating a new User and setting its Roles property to a new instance of UserRoles, the UserRoles object is not saved.

Here is my abridged User.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="DistrictObservations.User, DistrictObservations" table="users">
    <cache usage="read-write" region="all" />

    <id name="ID" column="id" type="int" unsaved-value="0">
      <generator class="identity" />
    </id>

    <!-- snip -->

    <one-to-one name="Roles" class="DistrictObservations.UserRoles, DistrictObservations" lazy="false" />

  </class>
</hibernate-mapping>

And here is the UserRoles mapping:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="DistrictObservations.UserRoles, DistrictObservations" table="user_roles">
    <cache usage="read-write" region="all" />

    <id name="UserID" column="user_id" type="int" >
      <generator class="foreign">
        <param name="property">User</param>
      </generator>
    </id>

    <!-- snip -->

    <one-to-one name="User" class="DistrictObservations.User, DistrictObservations" lazy="false" constrained="true" foreign-key="FK_user_roles_users" />

  </class>
</hibernate-mapping>

Anyone got an idea how to have the UserRoles object saved with the User.ID as its primary key? I've been looking at the documentation, and to be honest, it is not particularly helpful.

A: 

I'm probably missing something, but do you need a one-to-one between User and UserRoles? Can you not just have a one-to-many between User and Role? UserRoles seems redundant.

James L
A: 

I have found the one-to-one mapping to be rarely necessary. What I would often think of as a one-to-one is usually a one-to-many mapping. The same value as the primary key on two tables is not something is a common occurrence.

Judging from the looks of the class names it seems that you are trying to associate roles to a user? That does not look like a one-to-one to me.

That said, it looks like the generator of class foreign should do what you need.

Jim Petkus
i may change the schema... I'm using the foreign generator, but it isn't working when I do a sess.Save(user)
SoloBold
+2  A: 

Usually you don't need one-to-one, unless you're stuck with an immutable legacy database schema. Most User-Role mappings allow for users to be in multiple roles and roles to be allowed to be used by any number of users, which means an associative table for a many-to-many association.

If your app only needs one role per user ever, then I suggest putting the RoleId as a FK in the Users table directly.

That being said, if you stick to a one-to-one for whatever reason, make sure you use inverse="true" on the one that will not be doing the updating (the 'child' entity). (See the Hibernate one-to-one docs for more info on the inverse attribute--it should explain enough about it.)

Mufasa
inverse is not an attribute of one-to-one. maybe i will change the schema though. UserRoles is a row of boolean values at the moment...
SoloBold