2017-10-11 2 views
0

ich mit einem Frühlings-Boot-Projekt mit MySQL-Datenbank arbeiten und die Einheiten vorgesehen sind,com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException doppelten Eintrag

Die IP-Adresse Einheit,

@Entity 
public class IpAddress { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "IP_ADDR_ID") 
    private Long id; 

    @Column(name = "IP_ADDRESS") 
    @NotEmpty 
    private String address; 


    @JsonIgnore 
    @ManyToMany(cascade = CascadeType.ALL, mappedBy = "ipAddresses") 
    private List<HttpInfoMessage> httpInfoMessages = new ArrayList<>(); 

    public IpAddress() { 
    } 

    public IpAddress(String address) { 
     this.address = address; 
    } 

    public IpAddress(String address, List<HttpInfoMessage> httpInfoMessages) { 
     this.address = address; 
     this.httpInfoMessages = httpInfoMessages; 
    } 

    public Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 

    public String getAddress() { 
     return address; 
    } 

    public void setAddress(String address) { 
     this.address = address; 
    } 

    public List<HttpInfoMessage> getHttpInfoMessages() { 
     return httpInfoMessages; 
    } 

    public void setHttpInfoMessages(List<HttpInfoMessage> httpInfoMessages) { 
     this.httpInfoMessages = httpInfoMessages; 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (!(o instanceof IpAddress)) return false; 

     IpAddress ipAddress = (IpAddress) o; 

     if (!getId().equals(ipAddress.getId())) return false; 
     return getAddress().equals(ipAddress.getAddress()); 
    } 

    @Override 
    public int hashCode() { 
     int result = getId().hashCode(); 
     result = 31 * result + getAddress().hashCode(); 
     return result; 
    } 

    @Override 
    public String toString() { 
     return "IpAddress{" + 
       "id=" + id + 
       ", address='" + address + '\'' + 
       '}'; 
    } 
} 

Die Http Nachrichteneinheit,

@Entity 
public class HttpInfoMessage { 

    @Id 
// @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "STATUS_ID") 
    private Long statusId; 

    @Column(name = "STATUS") 
    @NotEmpty 
    private String status; 

    public HttpInfoMessage() { 

    } 

    public HttpInfoMessage(String status) { 
     this.status = status; 
    } 

    public HttpInfoMessage(Long statusId, String status) { 
     this.statusId = statusId; 
     this.status = status; 
    } 

    public HttpInfoMessage(Long statusId, String status, List<IpAddress> ipAddresses) { 
     this.statusId = statusId; 
     this.status = status; 
     this.ipAddresses = ipAddresses; 
    } 

    public Long getStatusId() { 
     return statusId; 
    } 

    public void setStatusId(Long statusId) { 
     this.statusId = statusId; 
    } 

    public String getStatus() { 
     return status; 
    } 

    public void setStatus(String status) { 
     this.status = status; 
    } 

    // @ManyToMany(cascade = CascadeType.ALL, mappedBy = "httpInfoMessages") 
    @ManyToMany(cascade = CascadeType.ALL) 
    @JoinTable(name = "IP_ADDR_STATUS", 
      joinColumns = @JoinColumn(name = "STATUS_ID", referencedColumnName = "STATUS_ID"), 
      inverseJoinColumns = @JoinColumn(name = "IP_ADDRESS_ID", referencedColumnName = "IP_ADDR_ID")) 
    private List<IpAddress> ipAddresses = new ArrayList<>(); 

    public List<IpAddress> getIpAddresses() { 
     return ipAddresses; 
    } 

    public void setIpAddresses(List<IpAddress> ipAddresses) { 
     this.ipAddresses = ipAddresses; 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (!(o instanceof HttpInfoMessage)) return false; 

     HttpInfoMessage httpInfoMessage1 = (HttpInfoMessage) o; 

     if (!getStatusId().equals(httpInfoMessage1.getStatusId())) return false; 
     return getStatus().equals(httpInfoMessage1.getStatus()); 
    } 

    @Override 
    public int hashCode() { 
     int result = getStatusId().hashCode(); 
     result = 31 * result + getStatus().hashCode(); 
     return result; 
    } 

    @Override 
    public String toString() { 
     return "Status{" + 
       "statusId=" + statusId + 
       ", status='" + status + '\'' + 
       '}'; 
    } 
} 

ich las die Serverprotokolleinträge aus einer Textdatei und eine gewisse Manipulation an ihnen durchführen und schließlich, erhalte ich die List<IpAddress>.

Nachdem ich die List<IpAddress>, ich druckte sie zeigen nur,

The IP list size is = 5 

IP address = IpAddress{id=null, address='177.132.239.67'} 
Status{statusId=403, status='403_Forbidden'} 
Status{statusId=404, status='404_Not Found'} 
Status{statusId=405, status='405_Method Not Allowed'} 
Status{statusId=406, status='406_Not Acceptable'} 

IP address = IpAddress{id=null, address='178.133.239.67'} 
Status{statusId=403, status='403_Forbidden'} 
Status{statusId=404, status='404_Not Found'} 
Status{statusId=405, status='405_Method Not Allowed'} 
Status{statusId=406, status='406_Not Acceptable'} 

IP address = IpAddress{id=null, address='175.130.239.67'} 
Status{statusId=403, status='403_Forbidden'} 
Status{statusId=404, status='404_Not Found'} 
Status{statusId=405, status='405_Method Not Allowed'} 
Status{statusId=406, status='406_Not Acceptable'} 

IP address = IpAddress{id=null, address='176.131.239.67'} 
Status{statusId=403, status='403_Forbidden'} 
Status{statusId=404, status='404_Not Found'} 
Status{statusId=405, status='405_Method Not Allowed'} 
Status{statusId=406, status='406_Not Acceptable'} 

IP address = IpAddress{id=null, address='174.129.239.67'} 
Status{statusId=403, status='403_Forbidden'} 
Status{statusId=404, status='404_Not Found'} 
Status{statusId=405, status='405_Method Not Allowed'} 
Status{statusId=406, status='406_Not Acceptable'} 

Ich habe dann versucht, durch Iteration durch sie alle Einträge zu speichern,

ipAddresses.forEach(
       ipAddress -> { 
        ipAddressService.save(ipAddress); 
       } 
     ); 

ich den Fehler bei der Zeitpunkt der Speicherung der Einträge,

java.lang.IllegalStateException: Failed to execute CommandLineRunner 

Caused by: org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [PRIMARY]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement 

Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement 

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '403' for key 'PRIMARY' 

Ich kann mehr Informationen zur Verfügung stellen, wenn erforderlich d

Antwort

1

Jedes der IpAddress-Objekte enthält eine Liste von HttpInfoMessage-Objekten, die das Feld "statusId" als ID in der Datenbank verwenden. Eine ID muss eindeutig sein.

Aber Sie verwenden die CascadeType.ALL für diese Sammlungen, was bedeutet, dass HttpInfoMessage Objekte auch gespeichert werden.

Also wenn Sie versuchen, die Status{statusId=403, status='403_Forbidden'} ein zweites Mal zu speichern, erhalten Sie die Ausnahme, weil die ID bereits existiert. Das ist ein einfacher Datenbankkram, und Sie müssen das beheben. Wie, hängt davon ab, was Sie tun möchten.

+0

Ich denke, die 'IpAddress'' id'-Spalte in der 'HttpInfoMessage'-Tabelle zuzuweisen, löst das Problem, obwohl ich mich frage, wie es geht. In dieser Zeit wird gespeichert wie 'Status {statusId = 403, status = '403_Forbidden', id = 1}', 'Status {statusId = 403, status = '403_Forbidden', id = 2}' usw. und wird eindeutig sein . Ich werde auch jede andere bessere Lösung öffnen. – Arefe

+0

Wenn ich 'CascadeType.MERGE' oder' CascadeType.DETACH' verwende, wird nur die Tabelle 'ip_address' aufgefüllt. Ich würde es vorziehen, wenn möglich alle Tabellen zu füllen. Bitte Beratung – Arefe

+0

Was Sie vorschlagen, ist eine OneToMany-Beziehung. Hier https: //en.wikibooks.org/wiki/Java_Persistence/OneToMany, wenn Sie wissen wollen, wie es geht. Für mich sind die Werte statische Werte, daher würde ich eine Enum- oder Datenbanktabelle mit aufgezählten Werten verwenden –

1

In Ihrer httpService-Entität ist das Feld statusId der Primärschlüssel. Ihre Testdaten haben die Werte 403-406 in statusId in jedem IpAddress -Block gesetzt. Wenn Sie die Werte von statusId entfernen und sie auf null setzen, sollte es funktionieren.

+0

Wie entferne ich die Werte von 'statusId'? – Arefe

+0

Erstellen Sie die Liste manuell? Dann setzen Sie den Wert auch manuell auf Status.statusId. Ansonsten müssen Sie über alle Status-Elemente iterieren und etw aufrufen. wie status.setStatusId = null. –

1

Sie versuchen, nicht eindeutige http-Statuscodes als Ids statusId einzugeben, die eindeutig sind.

Da Sie Ihre Entitäten zur Verfügung gestellt haben und Sie sie nicht ändern können, müssen Sie sicherstellen, dass Sie Werte korrekt als Status einfügen. Für mich mit einer solchen Entität kannst du eine technische (generierte) ID zu statusId und einen Namen deines Status ('403_Forbidden' oder einfach '403') in die Statusspalte setzen.

Verwandte Themen