使用连接表的JPA一对多单向关系

时间:2011-06-08 11:13:52

标签: java jpa jpa-2.0 eclipselink

我想在现有项目上评估JPA。数据库模型和java类存在,并且当前通过自生成代码进行映射。数据库模型和java类不能完美地匹配在一起 - 但是自定义映射很有效。尽管如此,JPA的使用似乎值得一试。

如您所见,我是JPA的新手,必须使用xml配置。目前我正在使用连接表进行一对多单向关系(请不要在此讨论这个szenario)。

A (one - relationship owner) <-> AB (JoinTable) <-> B (many)

表格看起来像这样

A
--
ID
BREF
...

B
--
ID
...

AB
--
A_BREF      (foreign key to a reference column in A which is NOT the id)
B_ID

我想为A类定义单向一对多关系。

class A {

 private List<B> bs;

}

并且这样做了:

<one-to-many name="bs">
    <join-table name="ab">
        <join-column name="a_bref">
            <referenced-column-name name="bref" />
        </join-column>
        <inverse-join-column name="b_id">
            <referenced-column-name name="id" />
        </inverse-join-column>
    </join-table>
</one-to-many>

虽然这不会强制错误它不起作用。问题是连接表不适用于A的ID列。查询选择&#34; B&#34;实体使用A.ID列值而不是A.BREF列值来选择实体。

(如何)我可以使这个映射工作(我使用eclipselink 2.2.0)?

感谢您的任何建议!


修改

在查看@ SJuan76回答中提供的链接后,我稍微修改了我的映射到

<one-to-many name="bs">
    <join-table name="ab">
        <join-column name="a_bref" referenced-column-name="bref" />
        <inverse-join-column name="b_id" referenced-column-name="id" />
    </join-table>
</one-to-many>

现在导致以下错误(使用eclipselink 2.1.0和2.2.0测试)

eclipselink 2.1.0

  

异常说明:参数   在查询的选择中命名[bref]   条件与任何参数都不匹配   在查询中定义的名称。

eclipselink 2.2.0

  

异常说明:参考   列名[bref]映射到   element [field bs]没有   对应于有效字段   映射参考。

顺便说一句 - 如果我从定义中删除referenced-column-name="bref",我会在inverse-join-column元素上获得referenced-column-name="id"的相同异常。所以我怀疑我是否理解referenced-column-name正确。我用它来指定与连接表相关的表的数据库列名。这是对的吗?


解决方案

我的szenario中的最后一个错误是我的班级没有确定BREF字段

class A {
    private long bref; // missing !
    private List<B> bs; 
}

和我的orm.xml此类的映射文件

<basic name="bref">
    <column name="bref" />
</basic>

我不知道我必须在我的映射类中的某处定义使用的连接映射referenced-column-name属性(因为我也没有连接表本身或连接的name属性 - column / inverse-join-column映射到类或类成员。)

检查案件问题的提示对我有帮助。我现在觉得在指定我的映射时非常详细,因为我用小写值覆盖所有默认(大写)映射。由于我的数据库不区分大小写,因此如果需要特殊映射以使用默认值,我将使用大写表示法。

为所有人+1!

3 个答案:

答案 0 :(得分:1)

答案 1 :(得分:1)

通常,JPA要求外键/连接列引用实体的主键/ Id。但是,这应该适用于EclipseLink,因此请包含正在生成的SQL,如果错误,请记录错误。

如何定义A的ID,它只是ID还是ID和BREF?

您可以使用DescriptorCustomizer为关系自定义ManyToManyMapping并设置正确的外键字段名称。

答案 2 :(得分:1)

您是否可以尝试将字段定义为“BREF”或者在属性映射中定义它时使用的相同确切情况,或者您可以尝试将eclipselink.jpa.uppercase-column-names持久性属性设置为true。当删除referenced-column-name =“bref”时,这可能是“id”的问题,因为实体中的字段可能默认为“ID”。