Java 非主键列的OneToOne关系
当我查询一个与另一个实体有一对一关系的实体时,我遇到了一个问题。这是一个场景: 数据库表:Java 非主键列的OneToOne关系,java,jakarta-ee,jpa,one-to-one,joincolumn,Java,Jakarta Ee,Jpa,One To One,Joincolumn,当我查询一个与另一个实体有一对一关系的实体时,我遇到了一个问题。这是一个场景: 数据库表: create table people ( id decimal(10,0) NOT NULL, email varchar(512) NOT NULL ); create table users ( email varchar(512) NOT NULL ); insert into users (email) values ('jhon@domain.com'); inse
create table people (
id decimal(10,0) NOT NULL,
email varchar(512) NOT NULL
);
create table users (
email varchar(512) NOT NULL
);
insert into users (email) values ('jhon@domain.com');
insert into users (email) values ('mary@domain.com');
insert into people (id, email) values (1, 'jhon@domain.com');
insert into people (id, email) values (2, 'mary@domain.com');
@Entity(name = "people")
public class Person implements Serializable {
@Column
@Id
private long id;
@Column
private String email;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
@Entity(name = "tbl_users")
public class User implements Serializable {
@Id
private String email;
@OneToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name = "email", referencedColumnName = "email")
private Person person;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
...
User user = entityManager.find(User.class, "jhon@domain.com");
...
测试数据:
create table people (
id decimal(10,0) NOT NULL,
email varchar(512) NOT NULL
);
create table users (
email varchar(512) NOT NULL
);
insert into users (email) values ('jhon@domain.com');
insert into users (email) values ('mary@domain.com');
insert into people (id, email) values (1, 'jhon@domain.com');
insert into people (id, email) values (2, 'mary@domain.com');
@Entity(name = "people")
public class Person implements Serializable {
@Column
@Id
private long id;
@Column
private String email;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
@Entity(name = "tbl_users")
public class User implements Serializable {
@Id
private String email;
@OneToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name = "email", referencedColumnName = "email")
private Person person;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
...
User user = entityManager.find(User.class, "jhon@domain.com");
...
实体:
create table people (
id decimal(10,0) NOT NULL,
email varchar(512) NOT NULL
);
create table users (
email varchar(512) NOT NULL
);
insert into users (email) values ('jhon@domain.com');
insert into users (email) values ('mary@domain.com');
insert into people (id, email) values (1, 'jhon@domain.com');
insert into people (id, email) values (2, 'mary@domain.com');
@Entity(name = "people")
public class Person implements Serializable {
@Column
@Id
private long id;
@Column
private String email;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
@Entity(name = "tbl_users")
public class User implements Serializable {
@Id
private String email;
@OneToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name = "email", referencedColumnName = "email")
private Person person;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
...
User user = entityManager.find(User.class, "jhon@domain.com");
...
调用:
create table people (
id decimal(10,0) NOT NULL,
email varchar(512) NOT NULL
);
create table users (
email varchar(512) NOT NULL
);
insert into users (email) values ('jhon@domain.com');
insert into users (email) values ('mary@domain.com');
insert into people (id, email) values (1, 'jhon@domain.com');
insert into people (id, email) values (2, 'mary@domain.com');
@Entity(name = "people")
public class Person implements Serializable {
@Column
@Id
private long id;
@Column
private String email;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
@Entity(name = "tbl_users")
public class User implements Serializable {
@Id
private String email;
@OneToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name = "email", referencedColumnName = "email")
private Person person;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
...
User user = entityManager.find(User.class, "jhon@domain.com");
...
取消调用后,hibernate的日志显示:
select user1_.email as email2_0_, person2_.id as id1_1_, person2_.email as email1_1_
from users user1_ left outer join people person2_ on user1_.email=person2_.id
where user1_.email=?
正如您所看到的,加入是错误的,因为它将users.email与people.id进行比较(user1\u0.email=person2\u0.id),因此它返回一个用户,而不返回相应的个人
有没有关于如何修复它的想法
非常感谢 我认为您应该重新考虑您的数据模型。用户和个人之间的关系看起来更像是继承关系 有关您的映射的问题,请参见此处以进一步讨论: 严格地说,。它可能在一些JPA实现中工作,但并不合适 但是,我认为您可以通过使关系具有双向性并由具有非主键的一方拥有来实现这一点:
@Entity
public class Person {
@Id
private long id;
@OneToOne
@JoinColumn(name = "email")
private User user;
public String getEmail() {
return user.getEmail();
}
public void setEmail(String email) {
// left as an exercise for the reader
}
}
@Entity
public class User {
@Id
private String email;
@OneToOne(mappedBy = "user")
private Person person;
}
不过,我实际上还没有尝试过,所以请注意黑客。@在@OneToOne属性上不允许使用列:@Robbo_UK很好,谢谢。它应该是一个
@JoinColumn
,对吗?我已经更改了。您必须设置一个小型项目并对其进行测试。。我在尝试使用非PK字段引用表时遇到问题。。