2013-04-22 33 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

相关问题