我正在尝试使用 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对应的数据库Schema:
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) );
这里发生的事情如下。我有一个Phone
嵌入类的NormalizedNumber
类。但是,这normalizedNumber
不是主键,也不是@Id
类的。它有一个不同的key
领域@Id
。
一个UserPhone
类有一个类的引用Phone
。这是一种@ManyToOne
关系,因为许多用户可以共享同一部电话。该 UsersPhones
表不使用表的主键Phones
作为外键,而是使用NormalizedNumber
列。显然这在 JPA 中可能无效,但 OpenJPA 手册指出 OpenJPA 支持目标列不是主键的连接“与主键连接具有相同的语法”。
从手册中我被引导相信这也适用于嵌入式字段。但我想我一定误解了这一点,因为事实并非如此。这是我得到的例外:
“你不能加入'Phones.normalizedNumber'列。它不是由支持连接的映射管理的。”
现在,我已经用调试器逐步检查了 OpenJPA 两天,如果我做错了什么或者它不合法,因为我没有在任何文档中明确描述它,我会找到提示。我在 Javadoc 中发现 OpenJPAEmbedFieldStrategy
没有实现Joinable
. 所以也许我正在尝试不可能的事情。
因此,专家们的问题是:这是否允许?还是关系的目标不是嵌入字段(我猜除了@EmbeddedId)?
我可以覆盖嵌入NormalizedNumber
以将 normaizedNumber 定义为@Id
吗?