1)我有两个表,user和user_profile,具有OneToOne
关系,
用户表:
id,user_name,first_name,last_name-id有主键,
用户配置文件:
id、name、user_id-id具有主键,user_id具有外键带有用户表
2) 以下是两个JPA实体对象
用户:
@Entity
@Table(name = "user")
public class User{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;
@Column(name = "user_name",unique=true,nullable=false)
private String name;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name="user_id")
public UserProfile userProfile;
//with set/get methods
}
用户配置文件:
@Entity
@Table(name = "user_profile")
public class UserProfile {
@Id
@Column(name = "id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "user_id")
private Long userId;
@OneToOne(mappedBy="userProfile")
private User user;
// with set/get methods
}
当我试图插入这两个表时,我看到user_id
列被添加到具有值的USER表中,并且在USER_PROFILE表的user_id
列中没有看到任何值。
我是这个MySQL的新手,有人能告诉我如何解决这个问题吗?
您的映射是向后的。@JoinColumn应该在user上,而不是userProfile上。
one-to-one
关系的工作方式确实与您的代码所期望的有所不同?我只是试着在这里解释同样的东西:一对一映射的概念。解释映射。请阅读。
关键是,在one-to-one
关系中,您的DB设计有一些限制。该关系基于两个主键。user
表中的id
键列与user_profile
的id
列具有相同的值。
如果你想使用one-to-one
,你需要
- 更改您的表格
user_profile
: - 它将具有列
id
,该主键不是由标识生成的 - 它不再具有user_id
id
将由user
实例中的NHibernate填充user_profile
的映射必须遵循一对一的"从"映射
user_profile
id
映射的小草稿(id由"foreign"非标识生成)
// Anottation
@GenericGenerator(name = "generator", strategy = "foreign",
parameters = @Parameter(name = "field", value = "user"))
@Id
@GeneratedValue(generator = "generator")
@Column(name = "id", unique = true, nullable = false)
private Long id;
看看这里有一个很好的例子:一对一的例子(注解)。在这里,您将找到如何进行这种映射的所有答案和提示但也要考虑一对一映射是否正是您所需要的。因为它在现实生活中有点罕见
@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name="user_id")
public UserProfile userProfile;
这里的注释意味着USER表将包含一个列USER_ID,该列将是对USER_PROFILE表的外键引用。这就是你所期望的吗?我认为应该将其重命名为USER_PROFILE_ID。
在这里,您没有在另一个表中指定列,因此需要添加:
@JoinColumn(name = "USER_PROFILE_ID", referencedColumnName = "ID")
private UserProfile userProfile;
在UserProfile类中,您可以删除:
@Column(name = "user_id")
private Long userId;
然后,用户的ID应显示在user_PROFILE表的user列中。
一对一关系基于外键概念,其中一个表的主键用作代码中其他表的正常列,用于对进行分类
-
用户
-
用户配置文件
但是不是在UserProfile表的id上使用@joinColumn,而是在其他列上使用它
所以make是正确的连接应该在主键上进行,而不是在其他列上。
主键不应由标识生成。
正如其他人所提到的,@JoinColumn
放错了表。它应该包含在关系的拥有方,也就是包含外键的表中。在您的情况下,该表为UserProfile
。
用户配置文件
@Entity
@Table(name = "user_profile")
public class UserProfile {
@Id
@Column(name = "id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "user_id")
private Long userId;
@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name="user_id")
private User user;
// with set/get methods
}
用户
@Entity
@Table(name = "user")
public class User{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;
@Column(name = "user_name",unique=true,nullable=false)
private String name;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@OneToOne(mappedBy="user")
public UserProfile userProfile;
//with set/get methods
}
有关更多详细信息,请参阅我关于确定实体拥有方的博客条目。