2016-08-09 82 views
0

Ich habe Klasse ResponsedAd:Saving Element der Sammlung in Hibernate

@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) 
@Cascade(CascadeType.REMOVE) 
@JoinColumn(name = "AD",nullable = false) 
private Ad ad; 

@Column(nullable = false) 
private LocalDateTime dateTimeOfResponse; 

@ManyToOne(fetch = FetchType.EAGER) 
@JoinColumn(name = "CLIENT",nullable = false) 
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(){} 

Er hat @ManyToOne Beziehungen zu Klassen: Client, Ad, Übersetzer

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

    public static long getSerialversionuid() { 
     return serialVersionUID; 
    } 
    public List<Ad> getAds() { 
     return ads; 
    } 

    public void setAds(List<Ad> ads) { 
     this.ads = ads; 
    } 

    public void addAd(Ad ad){ 
     ads.add(ad); 
     ad.setClient(this); 
    } 

    public void removeAd(Ad ad){ 
     ads.remove(ad); 
     ad.setClient(null); 
    } 

    public List<ResponsedAd> getResponsedAds() { 
     return responsedAds; 
    } 

    public void addResponsedAd(ResponsedAd responsedAd){ 
     responsedAds.add(responsedAd); 
     responsedAd.setClient(this); 
    } 

    public void removeResponsedAd(ResponsedAd responsedAd){ 
     responsedAds.remove(responsedAd); 
     responsedAd.setClient(null); 
    } 

Ad:

@Entity 
@NamedQueries({ 
    @NamedQuery(name = "getAllAds", 
      query = "from Ad"), 
    @NamedQuery(name = "deleteById", 
    query = "delete from Ad where id = :id") 
}) 
@FieldNotMatch(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; 


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

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

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

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

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

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

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

    @Column(name = "AD_PUBLICATIO_DATE_TIME",nullable = false) 
    private LocalDateTime publicationDateTime; 

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

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

    public Ad(){} 

Es ist eine Methode zum Speichern ResponsedAd:

Nach dem Speichern habe ich entsprechende Zeile in der Tabelle Respeeded_Ad_Test.

Wenn ich Ad löschen möchte Ich habe einen Fehler, mein Client-Objekt von Methode unten hat 3 die gleiche ResponsedAd, und ich habe Ausnahme: gelöschtes Objekt würde durch Kaskade erneut gespeichert werden (gelöschtes Objekt aus Verknüpfungen entfernen).

Und ich weiß nicht, warum mein Mandant ResponsedAd Objekt wiederholt hat, während mein Client-Objekt Speicher haben nur 1 ResponsedAd Objekt

@Override 
    public void deleteById(long id) throws NonExistedAdException,UnacceptableActionForAcceptedAd{ 
     Ad ad = get(id); 
     if(ad.getStatus().equals(AdStatus.ACCEPTED)){ 
      throw new UnacceptableActionForAcceptedAd(); 
     } 
     List<ResponsedAd> list = new ArrayList<>(ad.getResponsedAds()); 
     list.stream().forEach(rad->{ 
      Translator translator = rad.getTranslator(); 
      Client client = rad.getClient(); 
      translator.removeResponsedAd(rad); 
      ad.removeResponsedAd(rad); 
      client.removeResponsedAd(rad); 
     }); 

     Client client = ad.getClient(); 
     client.removeAd(ad); 
    } 

verstehe ich, dass Problem bei der Rettung ResponsedAd Objekts ist, aber ich kann nicht Verstehen Sie das Erstellen mehrerer RespessedAd-Objekte für den Client. Hilfe bitte :)

Antwort

0

Problem war in eifrigen Initialisierung der Sammlungen. Weil diese Initialisierung doppelte Objekte lädt. Ich habe FetchType von EAGER nach LAZY geändert und das Problem ist gelöst)