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