多对多休眠 xml 配置

Many-to-many hibernate xml configuration

我有这样的DB关系

我想要多对多关系。在 PLAYERPRIVILEGE 之间。你能帮我修复我的 .xml 配置吗?

预期结果: 我希望能够执行:String hql = "from Player as p right outer join p.privilages as priv";

实际: 到目前为止我得到:

org.hibernate.MappingException: Foreign key (FK8CD18EE134F64423:PLAYER [ID])) must have same number of columns as the referenced primary key (PRIVILAGE [ID,PRIVILAGE])

<hibernate-mapping>
    <class name="model.Privilage" table="PRIVILAGE">
        <id name="id" type="int" >
            <column name="ID"  precision="5" scale="0"/>
            <generator class="increment"/>
        </id>

        <set name="players" table="PLAYER"
             inverse="false" lazy="true" fetch="select" cascade="all" >
            <key>
                <column name="ID"/>
            </key>
            <many-to-many entity-name="model.Player">
                <column name="ID" not-null="true" />
            </many-to-many>
        </set>

        <property name="privilage" type="string">
            <column name="PRIVILAGE" length="20" not-null="true" />
        </property>
    </class>
</hibernate-mapping>

<class name="model.Player" table="PLAYER">
    <id name="playerId" type="int" >
        <column name="ID" precision="5" scale="0"/>
        <generator class="sequence">
            <param name="sequence">PLAYER_SEQ</param>
        </generator>
    </id>
    <set name="privilages" table="PRIVILAGE"
         inverse="false" lazy="true" fetch="select" cascade="all" >
        <key>
            <column name="ID"/>
        </key>
        <many-to-many entity-name="model.Privilage">
            <column name="PRIVILAGE" not-null="true" />
        </many-to-many>
    </set>
    <!-- ... -->
</class>

您正在映射错误的关联 table 名称及其列。

1) 两边的关联table相同(PLAYER_PRIV):

<set name="privilages" table="PLAYER_PRIV"
    ...
</set>

<set name="players" table="PLAYER_PRIV"
    ...
</set>

2) Privilage 映射中的列:

<key>
   <column name="PRIV_ID"/>
</key>
<many-to-many entity-name="model.Player">
   <column name="PLAYER_ID" not-null="true" />
</many-to-many>

Player映射中是相反的:

<key>
   <column name="PLAYER_ID"/>
</key>
<many-to-many entity-name="model.Privilage">
   <column name="PRIV_ID" not-null="true" />
</many-to-many>

3)除此之外,您必须选择一侧为inverse。来自 documentation:

If the association is bidirectional, one side has to be the owner and one side has to be the inverse end (ie. it will be ignored when updating the relationship values in the association table).

4) 您可能不想在 many-to-many 关联中使用 cascade=all,因为在删除权限时您可能不想删除所有被授予权限的玩家。

您应该参考您的 many-to-many 关系 table 称为 PLAYER_PRIV:

<set name="privilages" table="PLAYER_PRIV"
     inverse="true" lazy="true" fetch="select">
    <key>
        <column name="ID"/>
    </key>
    <many-to-many entity-name="model.Privilage">
        <column name="PRIV_ID" not-null="true"/>
    </many-to-many>
</set>

<set name="players" table="PLAYER_PRIV"
     inverse="false" lazy="true" fetch="select">
    <key>
        <column name="ID"/>
    </key>
    <many-to-many entity-name="model.Player">
        <column name="PLAYER_ID" not-null="true"/>
    </many-to-many>
</set>