我有一个基本的SpringBoot 2.0.5.RELEASE应用程序。使用Spring Initializer,JPA,嵌入式Tomcat,Thymeleaf模板引擎并将其打包为可执行JAR文件。
我上了这个课:
public class User implements Serializable {
@OneToMany( cascade = CascadeType.ALL,orphanRemoval = true,
fetch = FetchType.EAGER,mappedBy = "user")
@JsonIgnore
private List<Wallet> wallets = new ArrayList<Wallet>();
..
}
和这个:
public class Wallet implements Serializable {
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "invoice_id")
@JsonIgnore
@NotNull
private Invoice invoice;
@OneToMany(mappedBy = "wallet",
cascade = CascadeType.ALL,
orphanRemoval = true, fetch = FetchType.LAZY)
@JsonIgnore
private Set<Purchase> purchases = new HashSet<>();
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "user_id" , nullable=false)
@JsonIgnore
private User user;
..
}
和另外一个:
public class Purchase implements Serializable {
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "wallet_id")
@JsonIgnore
Wallet wallet;
...
}
但是我从具有发票和采购的控制器中删除了一个钱包,并且该钱包属于一个用户,该钱包并未从数据库中删除
walletService.delete(walletService.findById(id).get());
这是服务方法:
@Transactional
public void delete(Wallet wallet) {
if (LOG.isDebugEnabled()) {
LOG.debug("deleting Wallet [ " + wallet + " ]");
}
wallet
.getPurchases()
.parallelStream()
.forEach(p -> purchaseService.delete(p));
walletRepository.delete(wallet);
}
和
@Transactional
public void delete (Purchase purchase ) {
purchaseRepository.delete (purchase);
}
在属性文件中:
spring.jpa.show-sql=true
我在控制台中看到的最后一个查询是这个:
select
purchases0_.wallet_id as wallet_i8_13_0_,
purchases0_.id as id1_13_0_,
purchases0_.id as id1_13_1_,
purchases0_.amount as amount2_13_1_,
purchases0_.wallet_id as wallet_i8_13_1_
from
t_purchase purchases0_
where
purchases0_.wallet_id=?
并且没有删除也没有例外! !
答案 0 :(得分:1)
我可以在这里想到2个案例
您已在mappedBy
类中添加了Wallet
,因此Purchase
是所有者实体,您需要从Purchases
中删除
尝试更改删除电子钱包的方法
@Transactional
public void delete(Wallet wallet) {
if (LOG.isDebugEnabled()) {
LOG.debug("deleting Wallet [ " + wallet + " ]");
}
wallet.getPurchases().removeAll();
walletRepository.delete(wallet);
}
理想情况下,您已经在CascadeType.ALL
中配置了Wallet
,因此
walletRepository.delete(wallet);
也应该删除Set<Purchase>
。
答案 1 :(得分:1)
在控制器中尝试:
user.getWallets().remove(wallet);
walletService.delete(wallet);
userService.save(user);
答案 2 :(得分:0)
这可能是解决方案:休眠配置-> orphanRemoval = true
仅在删除用户实体的情况下才删除钱包吗?
答案 3 :(得分:0)
当您尝试通过以下方式删除每个孩子时,就会出现问题 本身(而父母(即父母))仍对其进行引用,并且 因为参考上已设置了所有的级联(包括持久性) 并合并),这会使子项(即购买项)在 撤消删除操作。
源:JPA / Hibernate removing "child" entities
通过在父级上创建流,并更改钱包类以使购买关系上的级联删除类型,来删除子级:
@OneToMany(mappedBy = "wallet",
cascade = CascadeType.REMOVE, // <--- here should be changed
orphanRemoval = true, fetch = FetchType.LAZY)
@JsonIgnore
private Set<Purchase> purchases = new HashSet<>();
然后,您只需致电walletRepository.delete(wallet);
即可完全删除父母和子女。