Hibernate:在调用save()之前必须手动分配此类的ID

我在使用Hibernate和oneToMany映射时遇到了一些问题。

这是我的function:

  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 retailerList; @OneToMany(cascade = CascadeType.ALL, mappedBy = "location") private List 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 getRetailerList() { return retailerList; } public void setRetailerList(List retailerList) { this.retailerList = retailerList; } @XmlTransient public List getUserList() { return userList; } public void setUserList(List 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) 

您的id属性未设置。 这可能是因为DB字段未设置为自动递增? 你在用什么数据库? MySQL的? 你的字段是否设置为AUTO INCREMENT?