插入与@RepositoryRestResource 的级联,外键始终为 null
Insert cascade with @RepositoryRestResource, foreign key always null
也许我是在碰运气,但我正在尝试用 @RepositoryRestResource
实现一个存储库,但是 parent 的外键没有在 child 中设置。我将尝试解释我做了什么以及我发现了什么..
首先让我们展示一下我做了什么:
UML :
我的马铃薯实体:
@Data
@Entity
@Table(name = "POTATO")
public class PotatoEntity {
@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private BigInteger id;
@Column(name = "FIRSTNAME")
private String firstname;
@Column(name = "LASTNAME")
private String lastname;
@OneToMany(mappedBy = "potato", cascade = CascadeType.PERSIST)
private List<DetailPotatoEntity> detailPotatoList;
}
我的 DetailPotato 实体:
@Data
@Entity
@Table(name = "DETAIL_POTATO")
public class DetailPotatoEntity {
@Id
@Column(name = "ID")
private BigInteger id;
@Column(name = "WEIGHT")
private BigDecimal weight;
@Column(name = "HEIGHT")
private BigDecimal height;
@JoinColumn(name = "POTATO_ID", nullable = false)
@ManyToOne
@JsonBackReference(value = "potato-detailPotato")
private PotatoEntity potato;
}
我的马铃薯存储库:
@RepositoryRestResource(collectionResourceRel = "potatos", path = "potatos")
public interface PotatoRepository extends CrudRepository<PotatoEntity, BigInteger> {
}
问题是当我推送以下内容时 json :
{
"firstname":"patate",
"lastname":"potato",
"detailPotatoList": [
{
"weight":12,
"height":13
}
]
}
DETAIL_POTATO
中的 POTATO_ID
始终为空。通常,当你有自己的控制器和服务时,你会在每个 DetailPotatoEntity
中设置 PotatoEntity
并且一切都会好起来的。所以,我本以为 @RepositoryRestResource
会为我做这件事。但事实并非如此。
我怎么"solved"呢?还是我?:
@PrePersist
public void prePersist() {
detailPotatoList.forEach(detailPotato-> detailPotato.setPotato(this));
}
或
public void setDetailPotatoList(List<DetailPotato> detailPotatoList) {
detailPotatoList.forEach(detailPotato-> detailPotato.setPotato(this));
this.detailPotatoList = detailPotatoList;
}
我的问题是,我必须这样做是否正常? @RepositoryRestResource
应该自己管理吗?
这是我的观察:
-也许 @RepositoryRestResource
应该只用于一个实体?
-我尝试使用 DetailPotatoRepository 只是为了看看(如果您自己检查,请注意您需要删除 @RepositoryRestResource
注释的 PotatoRepository
才能工作):
@RepositoryRestResource(collectionResourceRel = "detailsPotato", path = "detailsPotato")
public interface DetailPotatoRepository extends CrudRepository<DetailPotatoEntity, BigInteger> {
}
当我推送以下内容时 json :
{
"weight":12,
"height":13,
"potato": {
"firstname":"pomme",
"lastname":"apple"
}
}
POTATO_ID
已设置,一切正常。
结论
当parent告诉他的child人坚持时,child人不知道谁是他的parent。但是,当 child 告诉他的 parent 坚持时,child 知道他的 parent。
问题又来了:@RepositoryRestResource
应该自己管理吗?或者 @RepositoryRestResource
应该只用于一个实体?
您正在使用双向关联。在这种情况下,您应该提供 synchronization 个实体。尝试在您的 Potato#detailPotatoList
setter 中实现它。像这样,例如:
public void setDetailPotatoList(List<DetailPotatoEntity> details) {
if (detailPotatoList != null) {
detailPotatoList.forEach(d -> d.setPotato(null));
}
if (details != null) {
details.forEach(d -> d.setPotato(this));
}
detailPotatoList = details;
}
看我的example.
也许我是在碰运气,但我正在尝试用 @RepositoryRestResource
实现一个存储库,但是 parent 的外键没有在 child 中设置。我将尝试解释我做了什么以及我发现了什么..
首先让我们展示一下我做了什么:
UML :
我的马铃薯实体:
@Data
@Entity
@Table(name = "POTATO")
public class PotatoEntity {
@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private BigInteger id;
@Column(name = "FIRSTNAME")
private String firstname;
@Column(name = "LASTNAME")
private String lastname;
@OneToMany(mappedBy = "potato", cascade = CascadeType.PERSIST)
private List<DetailPotatoEntity> detailPotatoList;
}
我的 DetailPotato 实体:
@Data
@Entity
@Table(name = "DETAIL_POTATO")
public class DetailPotatoEntity {
@Id
@Column(name = "ID")
private BigInteger id;
@Column(name = "WEIGHT")
private BigDecimal weight;
@Column(name = "HEIGHT")
private BigDecimal height;
@JoinColumn(name = "POTATO_ID", nullable = false)
@ManyToOne
@JsonBackReference(value = "potato-detailPotato")
private PotatoEntity potato;
}
我的马铃薯存储库:
@RepositoryRestResource(collectionResourceRel = "potatos", path = "potatos")
public interface PotatoRepository extends CrudRepository<PotatoEntity, BigInteger> {
}
问题是当我推送以下内容时 json :
{
"firstname":"patate",
"lastname":"potato",
"detailPotatoList": [
{
"weight":12,
"height":13
}
]
}
DETAIL_POTATO
中的 POTATO_ID
始终为空。通常,当你有自己的控制器和服务时,你会在每个 DetailPotatoEntity
中设置 PotatoEntity
并且一切都会好起来的。所以,我本以为 @RepositoryRestResource
会为我做这件事。但事实并非如此。
我怎么"solved"呢?还是我?:
@PrePersist
public void prePersist() {
detailPotatoList.forEach(detailPotato-> detailPotato.setPotato(this));
}
或
public void setDetailPotatoList(List<DetailPotato> detailPotatoList) {
detailPotatoList.forEach(detailPotato-> detailPotato.setPotato(this));
this.detailPotatoList = detailPotatoList;
}
我的问题是,我必须这样做是否正常? @RepositoryRestResource
应该自己管理吗?
这是我的观察:
-也许 @RepositoryRestResource
应该只用于一个实体?
-我尝试使用 DetailPotatoRepository 只是为了看看(如果您自己检查,请注意您需要删除 @RepositoryRestResource
注释的 PotatoRepository
才能工作):
@RepositoryRestResource(collectionResourceRel = "detailsPotato", path = "detailsPotato")
public interface DetailPotatoRepository extends CrudRepository<DetailPotatoEntity, BigInteger> {
}
当我推送以下内容时 json :
{
"weight":12,
"height":13,
"potato": {
"firstname":"pomme",
"lastname":"apple"
}
}
POTATO_ID
已设置,一切正常。
结论
当parent告诉他的child人坚持时,child人不知道谁是他的parent。但是,当 child 告诉他的 parent 坚持时,child 知道他的 parent。
问题又来了:@RepositoryRestResource
应该自己管理吗?或者 @RepositoryRestResource
应该只用于一个实体?
您正在使用双向关联。在这种情况下,您应该提供 synchronization 个实体。尝试在您的 Potato#detailPotatoList
setter 中实现它。像这样,例如:
public void setDetailPotatoList(List<DetailPotatoEntity> details) {
if (detailPotatoList != null) {
detailPotatoList.forEach(d -> d.setPotato(null));
}
if (details != null) {
details.forEach(d -> d.setPotato(this));
}
detailPotatoList = details;
}
看我的example.