I'm working an application with java. I am getting this error:
ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-54) DB2 SQL Error:
SQLCODE=-407, SQLSTATE=23502, SQLERRMC=TBSPACEID=2, TABLEID=1298, COLNO=0,
with this exception:
exception occurred: -- javax.persistence.PersistenceException:
org.hibernate.exception.ConstraintViolationException: could not execute statement
I looked for a solution and I getting this docs:
https://www.ibm.com/docs/en/cfm/2.0.0.3?topic=job-common-sql-errors-during-data-import
it helps me to get which column has the error. it's my primary key.
My primary generated my Station entity is:
#Named
#Entity
#Table(name = "STATION")
#AttributeOverride(name = "id", column = #Column(name = "PK_STATION_ID"))
public class Station extends AbstractEntity {}
my AbstractEntity is:
#MappedSuperclass
public abstract class AbstractEntity extends AbstractEntityWithoutId {
/**
*
*/
private static final long serialVersionUID = 8088586545483293731L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Override
public String getRefObject() {
return String.valueOf(super.hashCode());
}
#Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (other == null || getClass() != other.getClass()) {
return false;
}
AbstractEntity that = (AbstractEntity) other;
if (this.id == null || that.id == null) {
return super.equals(other);
}
return Objects.equals(id, that.id);
}
#Override
public int hashCode() {
if (id == null) {
return super.hashCode();
}
return Objects.hash(id);
}
}
How to resolve that? thanks in advance.
Related
when I use #OrderColumn annotation, Hibernate returns collection with 42075 [Null] records, but without #OrderColumn everything works perfectly why? I want to use field "OrderNumber" to have always ordered entity by this field. The type of this "OrderNumber" on PostgreSQL side is "serial" with auto increasing count.
DocTestEntity:
#Entity
#Table(name = "`Document`")
public class DocTestEntity implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "`Document_ID`")
private Integer id;
#ManyToMany
#JoinTable(name = "`DocumentEmployee`",
joinColumns = #JoinColumn(name = "`Document_ID`"),
inverseJoinColumns = #JoinColumn(name = "`Employee_ID`"))
#OrderColumn(name ="`OrderNumber`", updatable = false, insertable = false)
private List<EmployeeTestEntity> employeeEntityList;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public List<EmployeeTestEntity> getEmployeeEntityList() {
return employeeEntityList;
}
public void setEmployeeEntityList(List<EmployeeTestEntity> employeeEntityList) {
this.employeeEntityList = employeeEntityList;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DocTestEntity docEntity = (DocTestEntity) o;
return Objects.equals(id, docEntity.id);
}
#Override
public int hashCode() {
return Objects.hash(id);
}
#Override
public String toString() {
return "DocTestEntity{" +
"id=" + id +
'}';
}
}
EmployeeTestEntity:
#Entity
#Table(name = "`Employee`")
public class EmployeeTestEntity implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "`Employee_ID`")
private Integer id;
#Column(name = "`Employee_name`")
private String name;
#Column(name = "`Employee_surname`")
private String surname;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String employeeName) {
this.name = employeeName;
}
public String getSurname() {
return surname;
}
public void setSurname(String employeeSurname) {
this.surname = employeeSurname;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
EmployeeTestEntity that = (EmployeeTestEntity) o;
return Objects.equals(id, that.id);
}
#Override
public int hashCode() {
return Objects.hash(id);
}
#Override
public String toString() {
return "EmployeeTestEntity{" +
"id=" + id +
'}';
}
}
And Test DAO:
#Stateless
public class DocTestDAO {
#PersistenceContext
private EntityManager em;
public DocTestEntity selectDocumentByID(Integer id) {
var result = em.createQuery("SELECT DISTINCT a from DocTestEntity a " +
" WHERE a.id = :id ", DocTestEntity.class)
.setParameter("id", id)
.getResultStream()
.map(Optional::ofNullable)
.findFirst()
.flatMap(Function.identity())
.orElse(null);
System.out.println("List records count is: " + result.getEmployeeEntityList().size());
return result;
}
}
You don't need the OrderNumber column to be autoincremented, the hibernate can manage the order column itself depending on the order of the items in the collection employeeEntityList.
You should make the OrderNumber to be insertable and updatable (true by default):
#OrderColumn(name = "OrderNumber")
I would recommend cleaning up the code, removing these apostrophes from the column names
"`DocumentEmployee`" should be "DocumentEmployee". You mentioned that everything could work without #OrderColumn, so I suppose apostrophes don't affect the functionality but look weird.
Please let me know if this still doesn't work after mentioned updates.
Environment:
javaee 7
java 8
jpa 2
I got the error EntityNotFoundException when I make a query of Moviment and automatically tries to load the associated Espai after I have modifed Espai class to separate id and version in a separate class with the annotation #MappedSuperclass.
I can suspect that it is something related with equals() and hashCode() methods but I have not been able to figure out the problem.
Espai that works fine
#Entity
#Table(name = "a_espai")
public class Espai implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String nom;
private Integer version;
#ManyToOne
#JoinColumn(name = "idServei", referencedColumnName = "id")
private Servei servei;
...
#Override
public int hashCode() {
int hash = servei == null ? 1 : servei.getId();
return hash;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Espai)) {
return false;
}
Espai other = (Espai) obj;
return id != null && id.equals(other.getId());
}
}
Espai after change that provokes the error
#Entity
#Table(name = "a_espai")
public class Espai extends BaseEntity implements Serializable {
private String nom;
#ManyToOne
#JoinColumn(name = "idServei", referencedColumnName = "id")
private Servei servei;
#Override
public int hashCode() {
int hash = 0;
if (servei == null) {
return hash;
} else {
return servei.getId();
}
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Espai)) {
return false;
}
Espai other = (Espai) obj;
return getId() != null && getId().equals(other.getId());
}
}
Moviment class where Espai gets the error on eager loading
#Entity
#Table(name = "t_moviment")
public class Moviment extends BaseEntity implements Serializable {
private LocalDate dataInici;
private LocalDate dataFi;
private String observacio;
#ManyToOne
#Basic(optional = false)
#JoinColumn(name = "idEspai", referencedColumnName = "id")
private Espai espai;
...
}
**Espai before change that provokes the error**
#MappedSuperclass
public class BaseEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Version
protected Integer version;
public Integer getId() {
return id;
}
}
When a parent entity is persisted/merged via saveAndFlush, it tries to insert a new record for the child entity instead of finding/merging the existing record. This causes a SQLIntegrityConstraintViolationException error. I have also tried pulling the existing entity directly via the DAO, setting that to be the field in the parent entity, and then saving and flushing, and it still tries to insert a new record for the child entity field.
Any help is greatly appreciated!
Child Entity
#Entity
#Table(name = "DROPDOWN_TYPE", uniqueConstraints = {
#UniqueConstraint(columnNames = { "DROPDOWN_TYPE_TXT" }, name = "DROPDOWN_TYPE_TXT_UK") })
public class DropdownType {
#Id
#Column(name = "DROPDOWN_TYPE_TXT")
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DropdownType that = (DropdownType) o;
return text.equals(that.text);
}
#Override
public int hashCode() {
return text.hashCode();
}
}
Parent Entity
#Entity
#Table(name = "DROPDOWN", uniqueConstraints = {
#UniqueConstraint(columnNames = { "DROPDOWN_TXT", "DROPDOWN_TYPE_TXT" }, name = "DROPDOWN_UK") })
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Dropdown {
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = "DROPDOWN_OPTION_ID_GENERATOR")
#SequenceGenerator(allocationSize = 1, name = "DROPDOWN_OPTION_ID_GENERATOR", sequenceName = "DROPDOWN_OPTION_ID_SQ")
#Column(name = "DROPDOWN_OPTION_ID")
private Long id;
#ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST })
#JoinColumn(name = "DROPDOWN_TYPE_TXT", foreignKey = #ForeignKey(name = "DROPDOWN_TYPE_TXT_FK"))
private DropdownType dropdownType;
#Column(name = "DROPDOWN_TXT")
private String text;
#Column(name = "ACTIVE_FLG")
private Boolean active;
#Column(name = "LEGACY_FLG")
private Boolean legacy;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public DropdownType getDropdownType() {
return dropdownType;
}
public void setDropdownType(DropdownType dropdownType) {
this.dropdownType = dropdownType;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Boolean isActive() {
return active;
}
public void setActive(Boolean active) {
this.active = active;
}
public Boolean isLegacy() {
return legacy;
}
public void setLegacy(Boolean legacy) {
this.legacy = legacy;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Dropdown dropdown = (Dropdown) o;
return dropdownType.equals(dropdown.dropdownType) && text.equals(dropdown.text);
}
#Override
public int hashCode() {
int result = dropdownType != null ? dropdownType.hashCode() : 0;
result = 31 * result + (text != null ? text.hashCode() : 0);
return result;
}
}
If you are using hibernate as your JPA provider, be careful when you override equals and hashcode -- see this post
It may be, that your JPA provider does not consider your entities to be equal as loaded entities can be some CGLIB proxies in reality (probably better to use instanceof than to compare classes).
I have an EJB application in where I am using Entity beans for database. I have to Entity beans having unidirectional one to one relation, JobPositionEntity and CandidateEntity.
Here is CandidateEntity
#Entity
public class CandidateEntity extends BaseEntity {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private Long meritNumber;
private String seatNumber;
private String candidateName;
private String gender;
public Long getMeritNumber() {
return meritNumber;
}
public void setMeritNumber(Long meritNumber) {
this.meritNumber = meritNumber;
}
public String getSeatNumber() {
return seatNumber;
}
public void setSeatNumber(String seatNumber) {
this.seatNumber = seatNumber;
}
public String getCandidateName() {
return candidateName;
}
public void setCandidateName(String candidateName) {
this.candidateName = candidateName;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
#Override
public Long getId() {
return id;
}
#Override
public void setId(Long id) {
this.id = id;
}
#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 CandidateEntity)) {
return false;
}
CandidateEntity other = (CandidateEntity) 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.nisheeth.config.ejb.entity.CandidateEntity[ id=" + id + " ]";
}
}
Here is JobPositionEntity
#Entity
public class JobPositionEntity extends BaseEntity {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
#OneToOne(fetch = FetchType.EAGER, orphanRemoval = true, cascade = CascadeType.ALL)
private CandidateEntity candidate;
#ManyToOne(fetch = FetchType.EAGER)
private SeasonEntity season;
public SeasonEntity getSeason() {
return season;
}
public void setSeason(SeasonEntity season) {
this.season = season;
}
public CandidateEntity getCandidate() {
return candidate;
}
public void setCandidate(CandidateEntity candidate) {
this.candidate = candidate;
}
#Override
public Long getId() {
return id;
}
#Override
public void setId(Long id) {
this.id = id;
}
#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 JobPositionEntity)) {
return false;
}
JobPositionEntity other = (JobPositionEntity) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "com.nisheeth.config.ejb.entity.JobPositionEntity[ id=" + id + " ]";
}
}
I want to select candidates which are not in JobPositionEntity. I have this query which did not work for me:
select ce.candidateName, ce.id from JobPositionEntity jp left join jp.candidate ce where ce <> null
Can anyone help write this query? Thanks in advance.
you can use a SubQuery
select c from Candidate c where c.id not in
(select jp.candidate.id from JobPositionEntity jp)
for more information:
https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html#queryhql-subqueries
I have the following Entity in hibernate, using JPA annotations
#Entity
#IdClass(PurchaseCounter.PurchaseCounterPK.class)
#Table(name = "customer_purchases_counter")
public class PurchaseCounter {
public static class PurchaseCounterPK implements Serializable {
Integer customerId;
Integer purchaseId;
public PurchaseCounterPK(Integer customerId, Integer purchaseId) {
this.customerId = customerId;
this.purchaseId = purchaseId;
}
public Integer getCustomerId() {
return customerId;
}
public void setCustomerId(Integer customerId) {
this.customerId = customerId;
}
public Integer getPurchaseId() {
return purchaseId;
}
public void setPurchaseId(Integer purchaseId) {
this.purchaseId = purchaseId;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PurchaseCounterPK that = (PurchaseCounterPK) o;
if (customerId != null ? !customerId.equals(that.customerId) : that.customerId != null) return false;
if (purchaseId != null ? !purchaseId.equals(that.purchaseId) : that.purchaseId != null) return false;
return true;
}
#Override
public int hashCode() {
int result = customerId != null ? customerId.hashCode() : 0;
result = 31 * result + (purchaseId != null ? purchaseId.hashCode() : 0);
return result;
}
}
Integer customerId;
Integer purchaseId;
Integer count = 0;
#Id
#Column(name = "customer_id")
public Integer getCustomerId() {
return customerId;
}
public void setCustomerId(Integer customerId) {
this.customerId = customerId;
}
#Id
#Column(name = "purchase_id")
public Integer getPurchaseId() {
return purchaseId;
}
public void setPurchaseId(Integer purchaseId) {
this.purchaseId = purchaseId;
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
}
when I do a query using Criteria and using purchaseId and customerId as Restriction.eq filters, that's the query that gets generated:
select this_.customerId as customerId137_0_, this_.purchaseId as purchaseId137_0_, this_.count as count137_0_ from customer_purchases_counter this_ where this_.purchaseId=? and this_.customerId=?
that of course is wrong because the fields customerId and purchaseId are not renamed to their names that I specified using #Column????
Mapping seems to be correct. This is likely occurrence of HHH-4256 (Hibernate does not honor #Column(name=...) annotation with IdClass) . If so, then updating to the newer version of Hibernate offers solution.
Also according bug report using #Column annotation in IdClass is workaround.
I'm not sure if I understand correctly, but the #Column specified simply which column to map to your java data.
So you should not apply the #Column annotation to your getters, but rather to your variable declarations themselves.
#ID
#Column (name="customer_Id")
Integer customerId;
#ID
#Column (name="purchase_Id")
Integer purchaseId;