Hibernate: 对于这个类,id在调用save()之前必须手动分配。
Hibernate: 对于这个类,id在调用save()之前必须手动分配。
我在使用Hibernate和oneToMany
映射时遇到了一些问题。
这是我的函数:
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;
这是我的两个实体:
Location
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 + " ]"; }
Merchant
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)
admin 更改状态以发布 2023年5月23日
在Hibernate中分配主键
确保属性是数据库中的主键并且具有自动递增的功能。然后,使用IDENTITY在数据类中使用@GeneratedValue注解将其映射到数据类中。
@Entity @Table(name = "client") data class Client( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private val id: Int? = null )
GL