views:

1421

answers:

1

Hi all, I need to map two different classes to the same view and receive an error that a duplicate mapping exists. Is this possible in NHibernate? If not, can anyone give direction as to how I can solve this mapping problem.

I work with views which are set in stone. One view brings back data needed to split into two classes. The view looks like:

vw_player_points
----------------
Id
GameID
PlayerID
Points

The classes need to be 'player', with a list of games played

select gameid from vw_player_points where playerid = <PlayerID>

And each 'game' needs a list of players and their points:

select playerid, points from vw_player_points where gameid = <GameID>

I've tried table-per-concrete class inheritance aswell as mapping to the same view twice, but have had no joy :(

Here's the 'rough' mappings put into one xml snippet. Notice I also need to map to an interface (which works)

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DomainModel" namespace="Test">

  <class name="IPlayer" abstract="true">

    <id name="Id" column="id">
      <generator class="assigned"/>
    </id>

    <union-subclass name="Player" table="vw_player">
        <bag name="Games">
         <key column="player_id"/>
            <one-to-many class="Test.IGame" not-found="ignore"/>
        </bag>
    </union-subclass>

  </class>

  <class name="IGame" abstract="true">

    <id name="Id" column="game_id">
      <generator class="assigned"/>
    </id>

    <union-subclass name="Game" table="vw_player_points">
        <bag name="Points">
         <key column="game_id"/>
            <one-to-many class="Test.IPlayerPoints" not-found="ignore"/>
        </bag>
    </union-subclass>

  </class>

  <class name="IPlayerPoints" abstract="true">

    <id name="Id" column="id">
      <generator class="assigned"/>
    </id>

    <union-subclass name="PlayerPoints" table="vw_player_points">
      <property not-null="false" name="PlayerId" column="player_id"/>
      <property not-null="false" name="Points" column="points"/>
    </union-subclass>

  </class>

</hibernate-mapping>
+1  A: 

It seems impossible to map multiple classes to a single view when using abstract/sub-class mapping of the form:

<class name="I[Entity]" abstract="true">

    <union-subclass name="[Entity]">
        ...
    </union-subclass>

</class>

I ended up mapping directly to the concrete classes using the proprty-ref attribute which works correctly:

<class name="Game" table="vw_player_points">

    <id name="Id" column="id">
     <generator class="hilo"/>
    </id>

    <property not-null="false" name="GameId" column="gameid"/>

    <bag name="Points">
     <key column="gameid" property-ref="GameId"/>
     <one-to-many class="PlayerPoints" not-found="ignore"/>
    </bag>

</class>

<class name="PlayerPoints" table="vw_player_points">

    <id name="Id" column="id">
     <generator class="hilo"/>
    </id>

    <property not-null="false" name="PlayerId" column="playerid"/>
    <property not-null="false" name="Points" column="points"/>

</class>

Perhaps an 'abstract' sub-mapping type would negate the use of the union-subclass hack mapping to interfaces.

theGecko
it's clear!! nice one!
Eduardo Xavier
Sorry, but shouldn't it be <key column="playerid" /> in the bag?
Wen Q.