2016-07-22 10 views
0

Ich habe Entität Ad:Löschen von Einheit, die Bestandteil der Sammlung ist und Sammlung von anderen Einheiten in Hibernate

@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*/ 

Ad ist Bestandteil der Sammlung in Auftraggeber:

@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 und Client.class hat eine Sammlung von ResponseAd-Objekten:

@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(){} 

Ich möchte das nach dem Löschen von Ad-Objekt, alle Respo nseAd-Objekte aus der Sammlung wurden ebenfalls gelöscht.

Dafür habe ich:

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); 
} 

Sagen Sie mir bitte, wie kann ich dieses Recht zu tun? Ich habe sehr viele Beziehungen und wenn ich dies versuchen zu tun, bekomme ich Fehler

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] 

Antwort

0

Zu allererst

Sie brauchen nicht @NotNull zu verwenden, wenn Sie nullable = false bereits erklärt in @Column(nullable = false) haben.

Zweitens

Was Sie versuchen, Operationen in Cascade zu tun tut. Fügen Sie diese cascade = CascadeType.ALL oder vielleicht cascade = CascadeType.REMOVE zu Ihren @ManyToOne Tags hinzu und es sollte funktionieren.

verwenden als Referenz: JPA @ManyToOne with CascadeType.ALL

+0

Aber ich habe @ Cascade (CascadeType.ALL) mit jeder Sammlung. Ich verwende Hibernate-Sitzung für alle Aktionen – Yuriy

+0

Und ich brauche alle ResponseAd-Entitäten zu löschen, wenn ich ihre Eltern (Ad) löschen, aber nicht umgekehrt – Yuriy

+0

Sehen Sie dies [Frage] (http://stackoverflow.com/questions/6915102/Deleting- entity-causes-objectdeletedexception-in-hibernate) Es scheint, dass Sie zu viele remove-Befehle geben. – Julian

0

Kundencenter Objekt: Client client = rad.getClient(); habe zwei responsedAd-Objekte in einer Sammlung mit der gleichen ID, daher auch nach dem Löschen dieses responsedAd-Objekts: client.removeResponsedAd(rad); Client-Objekt hat einen mehr. Und jetzt ist die Hauptfrage, warum dieser Client zwei Objekte mit der gleichen ID hat.

Verwandte Themen