【问题标题】:Deleting entity, which is element of collection and has collection of another entities in Hibernate删除实体,它是集合的元素,并且在 Hibernate 中具有另一个实体的集合
【发布时间】:2016-07-22 16:58:51
【问题描述】:

我有实体广告:

@Entity
@NamedQueries({
    @NamedQuery(name =  "getAllAds",
            query = "from Ad"),
    @NamedQuery(name =  "deleteById",
    query = "delete from Ad where id = :id")
})
@FieldMatch(first = "initLanguage",second = "resultLanguage", message = "Languages must be different")
@Table(name = "AD_TEST")
public class Ad  implements Serializable{

    /**
     * Version of this class in production 
     */
    private static final long serialVersionUID = 1L;

    @Id
    @SequenceGenerator(name = "standard", initialValue = 1)
    @GeneratedValue(generator = "standard", strategy =GenerationType.SEQUENCE)
    @Column(name = "AD_ID")
    private long id;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "CLIENT",nullable = false)
    private Client client;

    @NotBlank
    @Column(name = "AD_NAME", nullable = false)
    private String name;

    @NotBlank
    @Column(name = "AD_DESC",nullable = false,length = 1000)
    @Lob
    @Size(min = 0, max = 1000)
    private String description;

    @Column(name = "AD_COUNTRY", nullable = false)
    private String country;

    @Column(name = "AD_CITY", nullable = false)
    private String city;


    @NotNull
    /**
     * Добавить проверку валидности даты
     */
    @DateTimeFormat(iso = ISO.DATE,pattern = "dd.MM.yyyy")
    @Column(name = "AD_END_DATE",nullable = false)
    private LocalDate endDate;

    @NotNull
    @Column(name = "AD_INIT_LANGUAGE",nullable = false)
    @Enumerated(EnumType.STRING)
    private Language initLanguage;

    @NotNull
    @Column(name = "AD_RESULT_LANGUAGE",nullable = false)
    @Enumerated(EnumType.STRING)
    private Language resultLanguage;

    @NotNull
    @Column(name = "AD_TRANSLATE_TYPE",nullable = false)
    @Enumerated(EnumType.STRING)
    private TranslateType translateType;

    @Lob
    @Column(name = "AD_FILE")
    private byte[] file;

    @NotNull
    @Column(name = "AD_COST",nullable = false,precision = 2)
    private double cost;

    @NotNull
    @Column(name = "AD_CURRENCY",nullable = false)
    @Enumerated(EnumType.STRING)
    private Currency currency;

    @Column(name = "AD_CREATING_DATE",nullable = false)
    private LocalDateTime creationDateTime;

    @Column(name = "AD_STATUS",nullable = false)
    @Enumerated(EnumType.STRING)
    private AdStatus status;

    @OnDelete(action = OnDeleteAction.CASCADE)
    @OneToMany(fetch = FetchType.EAGER,orphanRemoval = true,mappedBy = "ad")
    @Cascade(CascadeType.ALL)
    private List<ResponsedAd> responsedAds = new ArrayList<>();

    public Ad(){}
    /*Getters and setters,  hashCode and equals*/

广告是客户端中的集合元素:

@Entity
@NamedQueries({
    @NamedQuery(name =  "clientByEmail",
                query = "from Client client where client.email = :email")
})
@Table(name = "CLIENT_TEST")
@PrimaryKeyJoinColumn(name= "client_id")
public class Client extends User{

    /**
     * Version of this class in production 
     */
    private static final long serialVersionUID = 1L;

    @OneToMany(fetch = FetchType.EAGER,orphanRemoval = true,mappedBy = "client")
    @Cascade(CascadeType.ALL)
    public List<Ad> ads = new ArrayList<>();

    @OneToMany(fetch = FetchType.EAGER,orphanRemoval = true,mappedBy = "client")
    @Cascade(CascadeType.ALL)
    private List<ResponsedAd> responsedAds = new ArrayList<>();

    public Client(){}

Ad.class 和 Client.class 有 ResponseAd 对象的集合:

@Entity
@Table(name = "RESPONSED_AD_TEST")
@NamedQueries({
    @NamedQuery(name = "responsedAdsByAd",query="from ResponsedAd where ad = :ad")
})
@Component
public class ResponsedAd {

    @Id
    @SequenceGenerator(name = "standard", initialValue = 1)
    @GeneratedValue(generator = "standard", strategy =GenerationType.SEQUENCE)
    private long id;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "AD",nullable = false)
    private Ad ad;

    @Column(nullable = false)
    private LocalDateTime dateTimeOfResponse;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "CLIENT")
    private Client client;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "TRANSLATOR",nullable = false)
    private Translator translator;

    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    private ResponsedAdStatus status;


    public ResponsedAd(){}

我希望在删除 Ad 对象后,集合中的所有 ResponseAd 对象也都被删除。

为此我有:

public void deleteById(long id){
    Ad ad = get(id);
    CopyOnWriteArrayList<ResponsedAd> list = new CopyOnWriteArrayList<>(ad.getResponsedAds());
    list.forEach(rad->{
        Translator translator = rad.getTranslator();
        translator.removeResponsedAd(rad);
        ad.removeResponsedAd(rad);
        Client client = rad.getClient();
        client.removeResponsedAd(rad);
    });
    Client client = ad.getClient();
    client.removeAd(ad);
}

请告诉我,我怎样才能做到这一点?我有很多关系,当我尝试这样做时,我得到了错误

HTTP Status 500 - Request processing failed; nested exception is 
org.springframework.dao.InvalidDataAccessApiUsageException: 
deleted object would be re-saved by cascade (remove deleted object from associations): 
[ua.translate.model.ad.ResponsedAd#102]; nested exception is org.hibernate.ObjectDeletedException: 
deleted object would be re-saved by cascade (remove deleted object from associations): [ua.translate.model.ad.ResponsedAd#102]

【问题讨论】:

    标签: java hibernate relationship cascading-deletes


    【解决方案1】:

    首先,

    如果您已经在@Column(nullable = false) 中声明了nullable = false,则不需要使用@NotNull

    第二,

    您要做的是在 Cascade 中进行操作。将此cascade = CascadeType.ALLcascade = CascadeType.REMOVE 添加到您的@ManyToOne 标签中,它应该可以工作。

    将此作为参考:JPA @ManyToOne with CascadeType.ALL

    【讨论】:

    • 但我每个集合都有@Cascade(CascadeType.ALL)。我对所有操作都使用 Hibernate 会话
    • 当我删除它们的父(广告)时,我需要删除所有 responseAd 实体,反之则不然
    • 看到这个question 似乎你给出了太多的删除命令。
    【解决方案2】:

    我的客户对象:Client client = rad.getClient();集合中有两个具有相同 ID 的 responsedAd 对象,因此即使在删除此 responsedAd 对象后:client.removeResponsedAd(rad); 客户端对象还有一个。现在主要的问题是为什么这个客户端有两个具有相同 id 的对象。

    【讨论】:

      猜你喜欢
      • 2013-05-28
      • 2015-03-18
      • 2012-06-23
      • 2018-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多