java - mvc - Hibernate: los ids para esta clase se deben asignar manualmente antes de llamar a save()
spring java tutorial (1)
su atributo id no está configurado. esto PUEDE deberse al hecho de que el campo DB no está configurado para incrementarse automáticamente? ¿Qué DB estás usando? MySQL? ¿Está su campo configurado en AUTO INCREMENT?
Tengo algunos problemas con Hibernate y el mapeo oneToMany
.
Aquí está mi función:
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;
Aquí están mis dos entidades:
Ubicación
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 + " ]";
}
Comerciante
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 + " ]";
}
}
Y cada vez que llamo a mi función, obtengo:
org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save():
para esta línea:
location = this.locationDao.save(location);
No entiendo por qué. Porque en ese caso no hay necesidad de asignar manualmente la identificación de la ubicación, ya que se genera automáticamente. Debo haber hecho algo mal, pero después de 3 días buscando no encuentro.
Estoy usando PostGreSQL y la identificación es una identificación autogenerada con esta secuencia:
nextval(''location_id_seq''::regclass)`
EDIT SOLVE:
Ok gracias por tus respuestas.
Si puede ayudar a otra persona en el futuro, solo necesita modificar el parámetro de la identificación de la siguiente manera:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id",unique=true, nullable = false)