我在使用Hibernate和oneToMany映射时遇到了一些问题。
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;
这是我的两个实体:
位置
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。我一定做错了,但是三天后我找不到。
我正在使用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吗?