OpenJPA:ManyToOne 关系的目标可以是 @Embedded 字段吗?

发布于 2024-10-03 01:11:12 字数 2523 浏览 4 评论 0原文

我正在尝试使用 ManyToOne 关系,其中外键链接到目标类中的 @Embedded 字段。这可以很好地编译和增强,但运行此代码时,OpenJPA 会抛出异常。这是 OpenJPA 2.0.1 的情况。在代码中,它看起来像这样:

@Embeddable
public class NormalizedNumber {

    private String normalizedNumber;

    @Basic
    public String getNormalizedNumber() {
        return normalizedNumber;
    }

    /* ... */
}


@Entity
@Table(name = "Phones")
public class Phone {

    private String key;
    private NormalizedNumber normalizedNumber;

    @Id
    @Column(name = "IdKey", nullable = false)
    protected String getKey() {
        return key;
    }

    @Embedded
    public NormalizedNumber getNormalizedNumber() {
        return normalizedNumber;
    }

    /* ... */
}




@Entity
@Table(name = "UsersPhones")
public class UserPhone {

    private String key;
    private Phone device;

    @Id
    @Column(name = "IdKey", nullable = false)
    protected String getKey() {
        return key;
    }

    @ManyToOne
    @JoinColumn(name="DeviceId", referencedColumnName="NormalizedNumber")
    public Phone getDevice() {
        return this.device;
    }
}

MySQL 的相应数据库架构:

create table Phones (
    IdKey CHAR(32) BINARY,
    -- type discriminator (inheritance strategy is single table)
    UDType CHAR(2) BINARY,
    NormalizedNumber VARCHAR(100) BINARY NOT NULL,
    -- more columns here
    constraint Phones_PK primary key (IdKey) );

create table UsersPhones (
    IdKey CHAR(32) BINARY,
    DeviceId VARCHAR(100) BINARY NOT NULL,
    UserKey CHAR(32) BINARY,
    -- more columns here
    constraint UsersPhones_PK primary key (IdKey) );

这里发生的情况如下。我有一个嵌入 NormalizedNumber 类的 Phone 类。不过,normalizedNumber 不是主键,也不是类的 @Id。它有一个与 @Id 不同的 key 字段。

UserPhone 类具有对 Phone 类的引用。这是一个 @ManyToOne 关系,因为许多用户可以共享同一部手机。 UsersPhones 表不使用 Phones 表的主键作为外键,而是使用 NormalizedNumber 列。显然这在 JPA 中可能无效,但 OpenJPA 手册指出 OpenJPA 支持目标列不是主键的连接,“与主键连接具有相同的语法”。

从手册中我相信这也适用于嵌入式领域。但我想我一定误解了这一点,因为事实并非如此。这是我得到的异常:

“您无法加入列“Phones.normalizedNumber”。它不是由支持连接的映射管理的。”

现在,我已经使用调试器单步调试 OpenJPA 两天,以查找提示是否我做错了什么,或者它是否不合法,因为我没有在任何文档中找到明确描述的内容。我在 Javadoc 中发现了一个提示,即 OpenJPA 的 EmbedFieldStrategy 没有实现 Joinable。所以也许我正在尝试不可能的事情。

因此,专家们的问题是:这是否允许?或者关系的目标不能是嵌入字段(我猜@EmbeddedId 除外)?

我可以覆盖嵌入的 NormalizedNumber 以将normaizedNumber 定义为@Id 吗?

I am trying to use a ManyToOne relation where the foreign key links to an @Embedded field in the target class. This compiles and enhances fine, but when running this code, OpenJPA will complain with an exception. This is with OpenJPA 2.0.1. In code this looks like so:

@Embeddable
public class NormalizedNumber {

    private String normalizedNumber;

    @Basic
    public String getNormalizedNumber() {
        return normalizedNumber;
    }

    /* ... */
}


@Entity
@Table(name = "Phones")
public class Phone {

    private String key;
    private NormalizedNumber normalizedNumber;

    @Id
    @Column(name = "IdKey", nullable = false)
    protected String getKey() {
        return key;
    }

    @Embedded
    public NormalizedNumber getNormalizedNumber() {
        return normalizedNumber;
    }

    /* ... */
}




@Entity
@Table(name = "UsersPhones")
public class UserPhone {

    private String key;
    private Phone device;

    @Id
    @Column(name = "IdKey", nullable = false)
    protected String getKey() {
        return key;
    }

    @ManyToOne
    @JoinColumn(name="DeviceId", referencedColumnName="NormalizedNumber")
    public Phone getDevice() {
        return this.device;
    }
}

The corresponding database Schema for MySQL:

create table Phones (
    IdKey CHAR(32) BINARY,
    -- type discriminator (inheritance strategy is single table)
    UDType CHAR(2) BINARY,
    NormalizedNumber VARCHAR(100) BINARY NOT NULL,
    -- more columns here
    constraint Phones_PK primary key (IdKey) );

create table UsersPhones (
    IdKey CHAR(32) BINARY,
    DeviceId VARCHAR(100) BINARY NOT NULL,
    UserKey CHAR(32) BINARY,
    -- more columns here
    constraint UsersPhones_PK primary key (IdKey) );

What is happening here is the following. I have a Phone class which embeds a NormalizedNumber class. The normalizedNumber is not the primary key and not the @Id of the class, though. It has a different key field as @Id.

A UserPhone class has a reference to a Phone class. This is a @ManyToOne relation since many users can share the same phone. The UsersPhonestable does not use the primary key of the Phones table as foreign key but rather the NormalizedNumber column. Apparently this might not be valid in JPA, but the OpenJPA manual states that OpenJPA supports joins where the target column is not a primary key "with the same syntax as a primary key join".

From the manual I was led to believe that this would also work with embedded fields. But I guess I must have misinterpreted that because it doesn't. This is the exception I get:

"You cannot join on column 'Phones.normalizedNumber'. It is not managed by a mapping that supports joins."

I have now stepped through OpenJPA with a debugger for two days to find a hint if I do something wrong or if it just isn't legal because I don't find it described explicitly in any documentation. I found a hint in the Javadoc in that OpenJPA's EmbedFieldStrategy does not implement Joinable. So maybe I am trying the impossible.

Hence the question for the experts: Is this allowed? Or can the target of a relation not be an embedded field (except @EmbeddedId, I guess)?

Could I override the embedded NormalizedNumber to define the normaizedNumber as @Id?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文