【发布时间】:2015-04-14 14:34:13
【问题描述】:
我需要使用 uniqueidentifier 作为每个表的主键,而不是 ID(整数)。下面描述的逻辑适用于 ID(Integer),而不适用于 rowguid(uniqueidentifier)。
我在(MS SQL Server)数据库中有以下表格。
CREATE TABLE Person(
[ROWGUID] [uniqueidentifier] ROWGUIDCOL NOT NULL CONSTRAINT [DF_PERSON_ROWGUID] DEFAULT (newsequentialid()),
[NICKNAME] [varchar](15) NULL,
[EMAIL] [varchar](50) NULL,
[DATE_OF_BIRTH] [date] NULL)
CREATE TABLE School(
[ROWGUID] [uniqueidentifier] ROWGUIDCOL NOT NULL CONSTRAINT [DF_PERSON_ROWGUID] DEFAULT (newsequentialid()),
[PERSONID] [varchar](15) NULL,
[EMAIL] [varchar](50) NULL,
[DATE_OF_BIRTH] [date] NULL)
这是一对多的关系(一个人可能有多个学校)。 School 表的 PERSONID 是 Person 表的 ROWGUID。
在 JPA 方面,问题在于,我无法使用 school 插入 Person 对象。但是,我可以
- 将 Person 对象单独插入到表中,
- 为一个人创建一个选择语句并检索其学校。所以我相信它证明了 FK 关系很好。
回到我无法插入的问题;尝试坚持时出现以下异常;
无法将值 NULL 插入“PERSONID”列、“SCHOOL”表;列不允许空值。插入失败。
所以基本上,它不能创建一个 Person 对象,生成它的 ROWGUID,然后将它连接到表 School 的 PERSONID 列。这就是我的假设。我相信这是因为我在 JPA 端生成 ID 的方式。这是怎么回事;
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ROWGUID", columnDefinition = "uniqueidentifier")
private String rowguid;
...
public class School implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ROWGUID", columnDefinition="uniqueidentifier")
private String rowguid;
//bi-directional many-to-one association to Person
@ManyToOne
@JoinColumn(name="PROFILEID")
private Person person;
public School() {
}
...
知道如何克服它吗?
重要提示:当每个实体的主键为 ID(int) 时,相同的逻辑可以正常工作,如下所示;
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="ID")
private int id;
public class School implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="ID")
private int id;
//bi-directional many-to-one association to Person
@ManyToOne
@JoinColumn(name="PROFILEID")
private Person person;
public School() {
}
我转换下一代ID的时候基本有问题;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="ID")
private int id;
进入
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ROWGUID", columnDefinition="uniqueidentifier")
private String rowguid;
【问题讨论】:
-
如果你的 Person 总是需要上学,你可以使用@Inheritance(strategy = InheritanceType.JOINED)。基本上 School 扩展了 Person(但这可能是一个糟糕的设计)
-
请注意,并非所有 JPA 实现都是相同的。我假设您使用 OpenJPA2。我认为您只需要从 School 中删除“@GeneratedValue(strategy = GenerationType.IDENTITY)”。并将 Person 中的关系定义为 @ManyToMany(mappedBy="person")
-
Jama,是的,它是 openJpa。但是为什么要改变关系呢?你认为是一对多造成的问题?
-
是的。我认为在 Hibernate 中你可以指定外键注释(或类似的东西)。但是在 OpenJPA 中,您必须在 Parent 对象中使用 @ManyToMany(mappedBy="person"),并在 Child 对象中描述映射。 99% 肯定这是唯一的方法(不同的策略除外)。我试图解决同样的问题一段时间。
标签: java sql sql-server jpa