删除不工作的 JPA/Hibernate OneToMany OneTOOne

问题描述 投票:0回答:1

调用repository.delete(entity)时不会发生删除。类结构如下

用户--OneToMany-->车辆--OneToMnay-->合约

车辆--一对一--->激活

车辆类别如下

public class VehicleBE implements Serializable {

@ManyToOne
@JoinColumn(name = "users", referencedColumnName = "id")
private UsersBE users;

@OneToMany(mappedBy = "vehicle", orphanRemoval = true, cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.FALSE)
private List<ContractBE> contracts;

@OneToOne(mappedBy = "vehicle", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private ActivationBE activation;

User类如下:

   public class UsersBE implements Serializable {  

   @OneToMany(mappedBy = "users", fetch = FetchType.EAGER, orphanRemoval = true, cascade = CascadeType.ALL)
    private List<VehicleBE> vehicles;
}

合约类别如下

public class ContractBE implements Serializable {
    @ManyToOne
    @JoinColumn(name = "vehicle", referencedColumnName = "id")
    private VehicleBE vehicle;
}

Activation类如下

public class ActivationBE implements Serializable {

    @OneToOne
    @JoinColumn(name = "vehicle", referencedColumnName = "id")
    private VehicleBE vehicle;

    @OneToMany(mappedBy = "activation", fetch = FetchType.EAGER)
    private List<ProvisioningCertificateBE> provisioningCertificate;
}

当我打电话时

vehicleRepository.deleteById(vehicleMmaBE.getId());

车辆和与他相关的类别都不会被删除。我期待车辆、合同和激活被删除。

车辆的存储库类别如下

@Repository
@Transactional 
public interface VehicleRepository extends JpaRepository<VehicleBE, Long> {

当我打电话时

userRepository.deleteById(userId);

用户、车辆、合同和激活正在被删除。

按照要求完成代码,其中两个逻辑都可用

@Override

public ResponseEntity<String> deleteDataByVin(Vin vin) {
    // Some Code
            if (noOfVehiclesForUser == 1) {
                userRepository.deleteById(userId);  **//working fine**            
            } else { 
               vehicleRepository.deleteById(vehicleMmaBE.getId());             
            }
        } 
        return ResponseEntity.ok().build();
    }
}
hibernate jpa spring-data-jpa hibernate-mapping jparepository
1个回答
0
投票

JPA/Hibernate处理域模型中实体关系的级联删除的方式可以解释你的问题:

vehicleRepository.deleteById(vehicleMmaBE.getId());
不删除
Vehicle
、它的
Contracts
和它的
Activation

 UsersBE ---- * VehicleBE ---- * ContractBE
                   |
                   |
                   |
                   |
              ActivationBE

当您删除

User
时,由于
User
实体具有针对 VehicleBE
级联删除
设置(感谢
CascadeType.ALL
),它会将删除操作级联到与该
 关联的 
Vehicle
 实体User
。由于您的
Vehicle
实体还为
ContractBE
ActivationBE
设置了级联删除,因此删除
User
会级联删除与其链接的所有内容。

当您尝试直接删除

Vehicle
时,由于级联设置,删除操作应该级联到
ContractBE
ActivationBE
。如果没有发生这种情况,则触发删除操作时级联的配置方式或会话/事务状态可能存在问题。

阅读“JPA:单向多对一和级联删除”,您可以尝试使用 Hibernate 特定的注释,例如

@OnDelete(action = OnDeleteAction.CASCADE)
。这将利用数据库的级联删除功能,而不是仅仅依赖 JPA 或应用程序级逻辑。

Hibernate

@OnDelete
注释可以应用于关系的子端,确保删除
Vehicle
会自动触发删除相关的
Contract
Activation
实体。
但这也意味着您的数据库需要支持外键级联删除,并且它依赖于 Hibernate 特定的功能,这会降低 JPA 应用程序在不同持久性提供程序之间的可移植性。

@Entity
public class ContractBE implements Serializable {
    @ManyToOne
    @JoinColumn(name = "vehicle", referencedColumnName = "id")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private VehicleBE vehicle;
}

@Entity
public class ActivationBE implements Serializable {
    @OneToOne
    @JoinColumn(name = "vehicle", referencedColumnName = "id")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private VehicleBE vehicle;
}
© www.soinside.com 2019 - 2024. All rights reserved.