OpenJPA:ManyToOne 关系的目标可以是 @Embedded 字段吗?
我正在尝试使用 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 UsersPhones
table 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论