当我查询与另一个实体有OneToOne关系的实体时,我遇到了问题。这是场景:
数据库表:
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");
...
在de调用之后,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_.email = person2_.id )进行比较,因此它返回用户没有相应的人。
关于如何修复它的任何想法?
非常感谢!!
答案 0 :(得分:1)
我认为您应该重新考虑您的数据模型。 User和Person之间的关系看起来更像是继承。
对于你的映射问题,他们会在这里看到进一步的讨论:
JPA providers: why do relationships/FKs to non-PK columns work in Hibernate and EclipseLink?
Does the JPA specification allow references to non-primary key columns?
答案 1 :(得分:0)
严格来说,the JPA specification does not allow references to non-primary key columns。它可能适用于某些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;
}
我实际上并没有尝试过,所以告诫hackor 。