2016-04-14 7 views
0

Ich habe 2 Entitäten, die Geofence und Device sind, sobald der Benutzer einen Geofence zu einem Gerät zuweisen, wird eine Verknüpfung erstellt von GeofenceDevice Entity dargestellt.Hibernate ConstraintViolationException on delete

Das Problem ist, dass wenn ich ein GeofenceDevice Objekt löschen, möchte ich eine Fehlermeldung erhalten:

Cannot delete or update a parent row: a foreign key constraint fails (`db_gpstracking`.`tj_geofence_device_gdev`, CONSTRAINT `FKE085AA815DC5054A` FOREIGN KEY (`GDEV_GEOFENCE_ID`) REFERENCES `t_geofence_geo` (`GEO_ID`)) 

Hier ist mein Code:

Geräteeinheit

package com.sifast.gpstracking.model; 

import java.io.Serializable; 
import java.util.Date; 
import java.util.List; 

import javax.persistence.CascadeType; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.EnumType; 
import javax.persistence.Enumerated; 
import javax.persistence.FetchType; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.ManyToOne; 
import javax.persistence.OneToMany; 
import javax.persistence.Table; 
import javax.persistence.Temporal; 
import javax.persistence.TemporalType; 

import org.hibernate.annotations.NamedQueries; 
import org.hibernate.annotations.NamedQuery; 

import com.sifast.gpstracking.utils.TypeEnum; 

@NamedQueries({ @NamedQuery(name = "findDeviceByUniqueId", query = "from Device d where d.uniqueId = :uniqueId") }) 
@Entity 
@Table(name = "T_DEVICE_DEV") 
public class Device implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @Column(name = "DEV_ID", nullable = false) 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int id; 

    @Column(name = "DEV_NAME", length = 1024, nullable = false) 
    private String name; 

    @Column(name = "DEV_UNIQUE_ID", nullable = false, unique = true) 
    private String uniqueId; 

    // TODO Add column last modification and date insert in every table 
    @Column(name = "DEV_LAST_UPDATE", nullable = true) 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date lastUpdate; 

    @Column(name = "DEV_PROTOCOL", length = 1024, nullable = true) 
    private String protocol; 

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "device") 
    private List<Position> listPosition; 

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.DETACH) 
    @JoinColumn(name = "DEV_USER_ID", referencedColumnName = "USR_USER_ID", nullable = false) 
    private User user; 

    @Enumerated(EnumType.STRING) 
    @Column(name = "DEV_TYPE", nullable = false) 
    private TypeEnum type; 

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "device") 
    private List<GeofenceDevice> listGeofenceDevice; 

    public Device() { 
     super(); 
     // TODO Auto-generated constructor stub 
    } 

    public Device(String name, String uniqueId, Date lastUpdate, String protocol) { 
     this.name = name; 
     this.uniqueId = uniqueId; 
     this.lastUpdate = lastUpdate; 
     this.protocol = protocol; 
    } 

    public int getId() { 
     return id; 
    } 

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

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getUniqueId() { 
     return uniqueId; 
    } 

    public void setUniqueId(String uniqueId) { 
     this.uniqueId = uniqueId; 
    } 

    public Date getLastUpdate() { 
     return lastUpdate; 
    } 

    public void setLastUpdate(Date lastUpdate) { 
     this.lastUpdate = lastUpdate; 
    } 

    public String getProtocol() { 
     return protocol; 
    } 

    public void setProtocol(String protocol) { 
     this.protocol = protocol; 
    } 

    public List<Position> getListPosition() { 
     return listPosition; 
    } 

    public void setListPosition(List<Position> listPosition) { 
     this.listPosition = listPosition; 
    } 

    public User getUser() { 
     return user; 
    } 

    public void setUser(User user) { 
     this.user = user; 
    } 

    public TypeEnum getType() { 
     return type; 
    } 

    public void setType(TypeEnum type) { 
     this.type = type; 
    } 

    public List<GeofenceDevice> getListGeofenceDevice() { 
     return listGeofenceDevice; 
    } 

    public void setListGeofenceDevice(List<GeofenceDevice> listGeofenceDevice) { 
     this.listGeofenceDevice = listGeofenceDevice; 
    } 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + (int) (id^(id >>> 32)); 
     result = prime * result + ((uniqueId == null) ? 0 : uniqueId.hashCode()); 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     Device other = (Device) obj; 
     if (id != other.id) 
      return false; 
     if (uniqueId == null) { 
      if (other.uniqueId != null) 
       return false; 
     } else if (!uniqueId.equals(other.uniqueId)) 
      return false; 
     return true; 
    } 

    @Override 
    public String toString() { 
     return name; 
    } 

    // @PrePersist 
    // private void updateCreationDate() { 
    // //creationDate = ... 
    // } 
    // 
    // @PreUpdate 
    // private void updateModificationDate() { 
    // //creationDate = ... 
    // } 
} 

Gefence Einheit

GeofenceDevice Einheit

package com.sifast.gpstracking.model; 

import java.io.Serializable; 

import javax.persistence.CascadeType; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.FetchType; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.ManyToOne; 
import javax.persistence.Table; 

import org.hibernate.Query; 
import org.hibernate.annotations.NamedQueries; 
import org.hibernate.annotations.NamedQuery; 

@NamedQueries({ 
     @NamedQuery(name = "findGeofenceDeviceByGeofenceIdAndDeviceId", query = "from GeofenceDevice geoDev where geoDev.device = :device and geoDev.geofence = :geofence"), 
     @NamedQuery(name = "findAllGeofenceDeviceByGeofenceId", query = "from GeofenceDevice geoDev where geoDev.geofence = :geofence") }) 
@Entity 
@Table(name = "TJ_GEOFENCE_DEVICE_GDEV") 
public class GeofenceDevice implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @Column(name = "GDEV_ID", nullable = false) 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int id; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "GDEV_GEOFENCE_ID", referencedColumnName = "GEO_ID", nullable = false) 
    private Geofence geofence; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "GDEV_DEVICE_ID", referencedColumnName = "DEV_ID", nullable = false) 
    private Device device; 

    // si status == true alors la geofencing correspond à ce device est activé sinon il est désactivé 
    @Column(name = "GDEV_STATUS", nullable = true) 
    private boolean status; 

    // si inside == true alors c'est alerte d'entrée sinon c'est une alerte de sortie de la zone 
    @Column(name = "GDEV_ALERT_TYPE", nullable = true) 
    private boolean inside; 

    public GeofenceDevice() { 
     super(); 
     // TODO Auto-generated constructor stub 
    } 

    public GeofenceDevice(Geofence geofence, Device device, boolean status, boolean inside) { 
     this.geofence = geofence; 
     this.device = device; 
     this.status = status; 
     this.inside = inside; 
    } 

    public int getId() { 
     return id; 
    } 

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

    public Geofence getGeofence() { 
     return geofence; 
    } 

    public void setGeofence(Geofence geofence) { 
     this.geofence = geofence; 
    } 

    public Device getDevice() { 
     return device; 
    } 

    public void setDevice(Device device) { 
     this.device = device; 
    } 

    public boolean isStatus() { 
     return status; 
    } 

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

    public boolean isInside() { 
     return inside; 
    } 

    public void setInside(boolean inside) { 
     this.inside = inside; 
    } 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((device == null) ? 0 : device.hashCode()); 
     result = prime * result + ((geofence == null) ? 0 : geofence.hashCode()); 
     result = prime * result + (inside ? 1231 : 1237); 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     GeofenceDevice other = (GeofenceDevice) obj; 
     if (device == null) { 
      if (other.device != null) 
       return false; 
     } else if (!device.equals(other.device)) 
      return false; 
     if (geofence == null) { 
      if (other.geofence != null) 
       return false; 
     } else if (!geofence.equals(other.geofence)) 
      return false; 
     if (inside != other.inside) 
      return false; 
     return true; 
    } 

    @Override 
    public String toString() { 
     return "GeofenceDevice [geofence=" + geofence + ", device=" + device + "]"; 
    } 

} 

Und hier ist ein Link für die Logs

Antwort

0

Nach einigen Stunden fand ich eine Lösung für mein Problem!

Tatsächlich ist die Tatsache, dass eine Zeile aus einer Vereinigung von 2 Einheiten ist, Löschen eine orphanRemoval in Entity Relationships

damit die Änderungen genannt I in Code vorgenommen sind:

Geräteeinheit:

@OneToMany(fetch = FetchType.LAZY, mappedBy = "device", orphanRemoval=true) 

Geofence Einheit:

@OneToMany(fetch = FetchType.LAZY, mappedBy = "geofence", orphanRemoval=true) 
private List<GeofenceDevice> listGeofenceDevice; 
0

ich versuchen würde, mit Hibernate SQL-Protokolle zu öffnen:

org.hibernate.SQL=DEBUG 

Es aussieht wie du versuche irgendwo eine GeoFence Entity zu löschen und der FK auf GeoFenceDevice klagt.

+0

Dank @Franck, die Lösung für das Problem war die Verwendung von 'orphanRemoval'. Ich poste es in einer Antwort, die du sehen kannst;) –

Verwandte Themen