One to One relationship mapping JPA SpringBoot implementation error: ids for this class must be manually assigned before calling save()
One to One relationship mapping JPA SpringBoot implementation error: ids for this class must be manually assigned before calling save()
我正在尝试了解 JPA Spring 一对一映射的启动实现 classes,希望有人能给我提供清晰的图片。
- 一对一映射
场景:Table foo 和 Table childfoo
Foo 有 foo_id、foo_name、foo_place 列
childfoo 有 columnd foo_id(foo table 的外键), childfoo_name
这是我目前所做的 JPA 实体实现:
@Entity
@Data
@Table(name = "foo")
public class foo implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "foo_id")
private Integer fooId;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name="fooId")
private ChildFoo childFoo;
}
ChildFoo class
@Entity
@Data
@NoArgsConstructor
@EqualsAndHashCode(exclude ="foo")
@Table(name = "childfoo")
public class Childfoo implements Serializable {
/**
*
*/
private static final long serialVersionUID = -8142203085486540150L;
@Id
private Integer fooId;
@OneToOne(cascade = CascadeType.ALL, optional = false, fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn(name = "foo_id", referencedColumnName = "fooId")
private Foo foo;
@Column(name="child_name")
private String childName;
}
我已经为 Foo 创建了一个存储库并且我正在使用
FooRepository.save(foo)
在控制器中保存数据。
添加 foo 和 childfoo 的控制器代码:
Foo foo = new Foo();
foo.set...
ChildFoo childFoo = new ChildFoo();
childFoo.setChildName("abc");
childFoo.setFoo(foo);
foo.setChildFoo(childFoo);
fooRepository.save(foo);
但我收到错误消息:
此 class 的 ID 必须在调用 save() 之前手动分配。
从您的评论看来,您正在尝试使用 shared primary key strategy,其中 ChildFoo
也将使用 fooId
作为自己的主键。
如果是这样,那么我认为您需要更新一些 JPA 注释:
@Entity
@Data
@Table(name = "foo")
public class Foo implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "foo_id")
private Integer fooId;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "foo")
private ChildFoo childFoo;
}
@Entity
@Data
@NoArgsConstructor
@EqualsAndHashCode(exclude ="foo")
@Table(name = "childfoo")
public class ChildFoo implements Serializable {
private static final long serialVersionUID = -8142203085486540150L;
@Id
@Column(name = "foo_id")
private Integer fooId;
@OneToOne(cascade = CascadeType.ALL, optional = false)
@MapsId // primary key copied from Foo
@JoinColumn(name = "foo_id")
private Foo foo;
@Column(name="child_name")
private String childName;
}
并且您可能需要在关联和保存 ChildFoo
之前保存 Foo
的实例(从而生成共享 ID),但我认为一旦所有内容都被正确注释后就没有必要了。
说到注释,我只是从您的原始注释中删除了惰性提取类型以阐明更新。您应该能够毫无问题地包含它们。
其他有用的链接:
Shared primary key with JPA and Spring Boot
OneToOne shared primary key - JPA2.0 updates
我正在尝试了解 JPA Spring 一对一映射的启动实现 classes,希望有人能给我提供清晰的图片。
- 一对一映射 场景:Table foo 和 Table childfoo Foo 有 foo_id、foo_name、foo_place 列 childfoo 有 columnd foo_id(foo table 的外键), childfoo_name
这是我目前所做的 JPA 实体实现:
@Entity
@Data
@Table(name = "foo")
public class foo implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "foo_id")
private Integer fooId;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name="fooId")
private ChildFoo childFoo;
}
ChildFoo class
@Entity
@Data
@NoArgsConstructor
@EqualsAndHashCode(exclude ="foo")
@Table(name = "childfoo")
public class Childfoo implements Serializable {
/**
*
*/
private static final long serialVersionUID = -8142203085486540150L;
@Id
private Integer fooId;
@OneToOne(cascade = CascadeType.ALL, optional = false, fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn(name = "foo_id", referencedColumnName = "fooId")
private Foo foo;
@Column(name="child_name")
private String childName;
}
我已经为 Foo 创建了一个存储库并且我正在使用
FooRepository.save(foo)
在控制器中保存数据。
添加 foo 和 childfoo 的控制器代码:
Foo foo = new Foo();
foo.set...
ChildFoo childFoo = new ChildFoo();
childFoo.setChildName("abc");
childFoo.setFoo(foo);
foo.setChildFoo(childFoo);
fooRepository.save(foo);
但我收到错误消息:
此 class 的 ID 必须在调用 save() 之前手动分配。
从您的评论看来,您正在尝试使用 shared primary key strategy,其中 ChildFoo
也将使用 fooId
作为自己的主键。
如果是这样,那么我认为您需要更新一些 JPA 注释:
@Entity
@Data
@Table(name = "foo")
public class Foo implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "foo_id")
private Integer fooId;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "foo")
private ChildFoo childFoo;
}
@Entity
@Data
@NoArgsConstructor
@EqualsAndHashCode(exclude ="foo")
@Table(name = "childfoo")
public class ChildFoo implements Serializable {
private static final long serialVersionUID = -8142203085486540150L;
@Id
@Column(name = "foo_id")
private Integer fooId;
@OneToOne(cascade = CascadeType.ALL, optional = false)
@MapsId // primary key copied from Foo
@JoinColumn(name = "foo_id")
private Foo foo;
@Column(name="child_name")
private String childName;
}
并且您可能需要在关联和保存 ChildFoo
之前保存 Foo
的实例(从而生成共享 ID),但我认为一旦所有内容都被正确注释后就没有必要了。
说到注释,我只是从您的原始注释中删除了惰性提取类型以阐明更新。您应该能够毫无问题地包含它们。
其他有用的链接: Shared primary key with JPA and Spring Boot OneToOne shared primary key - JPA2.0 updates