2013-04-22 21 views
28

我在Hibernate和oneToMany映射中遇到了一些問題。休眠:這個類的ID必須在調用save()之前手動賦值()

這裏是我的功能:

 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; 

這裏是我的兩個實體:

位置

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 + " ]"; 
    } 

商人

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 + " ]"; 
    } 
} 

而且每次我打電話給我的功能時,我得到:

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

這條線:

location = this.locationDao.save(location); 

我不明白爲什麼。 因爲在那種情況下,不需要手動指定位置的ID,因爲它是自動生成的。 我一定做錯了什麼,但3天后看起來我沒有找到。

我使用PostgreSQL和ID是自動生成的ID與此序列:

nextval('location_id_seq'::regclass)` 

編輯解答:您的回答

好,謝謝。

如果它可以幫助其他人在未來,只需要通過修改ID的帕拉姆:

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

您正在使用的數據庫 – PSR 2013-04-22 08:01:41

+0

商戶正常工作的ü – PSR 2013-04-22 08:03:33

+0

試圖改變ID算法名稱到另一個測試 – PSR 2013-04-22 08:04:21

回答

18

你的id屬性未設置。這可能是由於DB字段未設置爲自動增量的事實?你在用什麼數據庫? MySQL的?你的字段是否設置爲AUTO INCREMENT?

+0

感謝您的回答。我使用自動生成的ID使用PostGre。我剛剛編輯了我的帖子。 MySQL和AI的 – Boris 2013-04-22 08:05:03

+6

,這個工程。你可能想檢查postgresql是否也是這種情況。我的POJO幾乎總是這個樣子:\t @Id \t @GeneratedValue(策略= GenerationType.IDENTITY) @Column(name = 「ID」,獨特= TRUE,可爲空= FALSE) 衆長的getId(){ 回報this.id; } – rmalchow 2013-04-22 08:08:42

+0

好的非常感謝。它似乎只是缺少獨特的=真... – Boris 2013-04-22 08:52:03

相關問題