2013-04-22 3 views
28

Ich habe einige Probleme mit Hibernate und dem oneToMany Mapping.Hibernate: IDs für diese Klasse müssen vor dem Aufruf von save() manuell zugewiesen werden.

Hier ist meine Funktion:

 Location location = new Location(); 
     location.setDateTime(new Date()); 
     location.setLatitude(lat); 
     location.setLongitude(lon); 

     location = this.locationDao.save(location); 

     merchant = new Merchant(); 
     merchant.setAddress(address); 
     merchant.setCity(city); 
     merchant.setCountry(country); 
     merchant.setLocation(location); 
     merchant.setName(name); 
     merchant.setOrganization(organization); 
     merchant.setPublicId(publicId); 
     merchant.setZipCode(zipCode); 
     merchant.setApplication(this.applicationDAO.findByPublicId(applicationPublicId)); 

     merchant = this.merchantDao.save(merchant); 

     return merchant; 

Hier sind meine zwei Entitäten:

Ort

import java.io.Serializable; 
import java.util.Date; 
import java.util.List; 
import javax.persistence.*; 
import javax.validation.constraints.NotNull; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlTransient; 


@Entity 
@Table(name = "location") 
@XmlRootElement 
public class Location implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Basic(optional = false) 
    @Column(name = "id", nullable = false) 
    private Long id; 

    @Basic(optional = false) 
    @NotNull 
    @Column(name = "latitude", nullable = false) 
    private double latitude; 

    @Basic(optional = false) 
    @NotNull 
    @Column(name = "longitude", nullable = false) 
    private double longitude; 

    @Basic(optional = false) 
    @NotNull 
    @Column(name = "date_time", nullable = false) 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date dateTime; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "location") 
    private List<Merchant> retailerList; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "location") 
    private List<MobileUser> userList; 

    public Location() { 
    } 

    public Location(Long id) { 
     this.id = id; 
    } 

    public Location(Long id, double latitude, double longitude, Date dateTime) { 
     this.id = id; 
     this.latitude = latitude; 
     this.longitude = longitude; 
     this.dateTime = dateTime; 
    } 

    public Long getId() { 
     return id; 
    } 
    //getters and setters 


    @XmlTransient 
    public List<Merchant> getRetailerList() { 
     return retailerList; 
    } 

    public void setRetailerList(List<Merchant> retailerList) { 
     this.retailerList = retailerList; 
    } 

    @XmlTransient 
    public List<MobileUser> getUserList() { 
     return userList; 
    } 

    public void setUserList(List<MobileUser> userList) { 
     this.userList = userList; 
    } 

    @Override 
    public int hashCode() { 
     int hash = 0; 
     hash += (id != null ? id.hashCode() : 0); 
     return hash; 
    } 

    @Override 
    public boolean equals(Object object) { 
     // TODO: Warning - this method won't work in the case the id fields are not set 
     if (!(object instanceof Location)) { 
      return false; 
     } 
     Location other = (Location) object; 
     if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { 
      return false; 
     } 
     return true; 
    } 

    @Override 
    public String toString() { 
     return "com.fgsecure.geoloc.entities.Location[ id=" + id + " ]"; 
    } 

Händler

import java.io.Serializable; 
import javax.persistence.*; 
import javax.validation.constraints.NotNull; 
import javax.validation.constraints.Size; 
import javax.xml.bind.annotation.XmlRootElement; 
import org.codehaus.jackson.annotate.JsonAutoDetect; 
import org.codehaus.jackson.annotate.JsonIgnore; 


@JsonAutoDetect 
@Entity 
@Table(name = "retailer") 
@XmlRootElement 

public class Merchant implements Serializable { 

    private static final long serialVersionUID = 1L; 
    @JsonIgnore 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Basic(optional = false) 
    @Column(name = "id", nullable = false) 
    private Long id; 
    @Basic(optional = false) 
    @NotNull 
    @Size(min = 1, max = 50) 
    @Column(name = "public_id", nullable = false, length = 50) 
    private String publicId; 
    @Basic(optional = false) 
    @NotNull 
    @Size(min = 1, max = 50) 
    @Column(name = "name", nullable = false, length = 50) 
    private String name; 
    @Size(max = 50) 
    @Column(name = "organization", length = 50) 
    private String organization; 
    @Size(max = 128) 
    @Column(name = "address", length = 128) 
    private String address; 
    @Size(max = 10) 
    @Column(name = "zip_code", length = 10) 
    private String zipCode; 
    @Size(max = 50) 
    @Column(name = "city", length = 50) 
    private String city; 
    @Size(max = 50) 
    @Column(name = "country", length = 50) 
    private String country; 
    @JoinColumn(name = "location_id", referencedColumnName = "id", nullable = false) 
    @ManyToOne(optional = false) 
    private Location location; 
    @JoinColumn(name = "application_id", referencedColumnName = "id", nullable = false) 
    @ManyToOne(optional = false) 
    private Application application; 


    public Merchant() { 
    } 

    public Merchant(Long id) { 
     this.id = id; 
    } 

    public Merchant(Long id, String publicId, String name) { 
     this.id = id; 
     this.publicId = publicId; 
     this.name = name; 
    } 

    //getters and setters 


    @Override 
    public int hashCode() { 
     int hash = 0; 
     hash += (id != null ? id.hashCode() : 0); 
     return hash; 
    } 

    @Override 
    public boolean equals(Object object) { 
     // TODO: Warning - this method won't work in the case the id fields are not set 
     if (!(object instanceof Merchant)) { 
      return false; 
     } 
     Merchant other = (Merchant) object; 
     if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { 
      return false; 
     } 
     return true; 
    } 

    @Override 
    public String toString() { 
     return "com.fgsecure.geoloc.entities.Retailer[ id=" + id + " ]"; 
    } 
} 

Und jedes Mal, wenn ich meine Funktion nenne ich:

org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): 

für diese Linie:

location = this.locationDao.save(location); 

Ich verstehe nicht, warum. Da in diesem Fall die ID des Standorts nicht manuell zugewiesen werden muss, da sie automatisch generiert wird. Ich muss etwas falsch gemacht haben, aber nach 3 Tagen suche ich nicht finden.

Ich verwende PostGreSQL und die ID ist eine automatisch generierte ID mit dieser Sequenz:

nextval('location_id_seq'::regclass)` 

EDIT LÖSEN:

Ok Vielen Dank für Ihre Antworten.

Wenn es eine andere Person in der Zukunft helfen kann, müssen nur durch den param der ID ändern:

@Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Basic(optional = false) 
    @Column(name = "id",unique=true, nullable = false) 
+0

die Datenbank Sie verwenden – PSR

+0

Händler ordnungsgemäß funktionieren für u es die Ausnahme ist, gibt nur – PSR

+0

versuchen, für – PSR

Antwort

18

Ihr id-Attribut nicht gesetzt ist. Dies kann darauf zurückzuführen sein, dass das DB-Feld nicht auf automatisches Inkrementieren eingestellt ist. Welche DB verwendest du? MySQL? Ist Ihr Feld auf AUTO INCREMENT eingestellt?

+0

Danke für die Antwort. Ich verwende PostGre mit automatisch generierter ID. Ich habe gerade meinen Beitrag bearbeitet. – Boris

+6

für MySQL und AI, das funktioniert. Vielleicht möchten Sie überprüfen, ob dies auch bei postgresql der Fall ist. mein POJOs ziemlich immer so aussehen: \t @Id \t @GeneratedValue (strategy = GenerationType.IDENTITY) @Column (name = "id", einzigartig = true, nullable = false) public Lange getId() {return this.id; } – rmalchow

+0

Ok vielen Dank. Es scheint nur das Einzigartige zu fehlen = wahr ... – Boris

Verwandte Themen