Award Entity
#JsonIgnore
#ManyToMany(mappedBy="awards", fetch=FetchType.LAZY)
private Set<Winner> winners = new HashSet<>();
Winner Entity
#ManyToMany(fetch=FetchType.LAZY)
#JoinTable(name="AWARD_ASSIGNMENT",
joinColumns={#JoinColumn(name="WINNER_ID", referencedColumnName="ID")},
inverseJoinColumns={#JoinColumn(name="AWARD_ID", referencedColumnName="ID")})
private Set<Award> awards = new HashSet<>();
I am calling this hibernate fetch method
return getSession().createQuery("from Winner").list();
Hashcode equals method overriding in Awards entity
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
result = prime * result + ((winners == null) ? 0 : winners.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Award other = (Award) obj;
if (id != other.id)
return false;
if (winners == null) {
if (other.winners != null)
return false;
} else if (!winners.equals(other.winners))
return false;
return true;
}
Winner entity
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((awards == null) ? 0 : awards.hashCode());
result = prime * result + (int) (id ^ (id >>> 32));
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Winner other = (Winner) obj;
if (awards == null) {
if (other.awards != null)
return false;
} else if (!awards.equals(other.awards))
return false;
if (id != other.id)
return false;
return true;
}
Overriding equals and hashcode methods as Many to Many relation is using SET.
Points to remember :
1) Make sure there are not Associations(One to many/ Many to many ..etc) in your hashcode or equal methods. while overriding hashcode / equals method use fields which make that object unique (ex.. FirstName + LastName + Phone number) try to avoid using PK Id generated by JPA .
2) Restrict Jackson/Json serialisation to avoid deep traversal .
#JsonManagedReference
private Set<Award> awards = new HashSet<>();
#JsonBackReference
private Set<Winner> winners = new HashSet<>();
Related
I am using Room SQLite wrapper library for my local database with an entity class includes Fileds of the table.
#Entity(tableName = DBContract.PatientDataEntry.TABLE_NAME)
public class PatientRecordEntity {
#PrimaryKey(autoGenerate = true)
#ColumnInfo(name = DBContract.PatientDataEntry._PID)
public int pid;
#ColumnInfo(name = DBContract.PatientDataEntry.COLUMN_PATIENT_ID)
public String patient_db_ID = "";
#ColumnInfo(name = DBContract.PatientDataEntry.COLUMN_PATIENT_RACE)
public String patient_race = "";
#ColumnInfo(name = DBContract.PatientDataEntry.COLUMN_PATIENT_REAL_IC)
public String patient_IC = "";
#ColumnInfo(name = DBContract.PatientDataEntry.COLUMN_BED_NO)
public String bed_number = "";
#ColumnInfo(name = DBContract.PatientDataEntry.COLUMN_REAL_BED_NO)
public String real_bed_number = "";
#ColumnInfo(name = DBContract.PatientDataEntry.COLUMN_NO_WOUNDS)
public int no_wounds = -1;
I wrote a test for the queries of this and add equal method to campare of the objects that stored in this database
public boolean equals(Object o) {
// If the object is compared with itself then return true
if (o == this)
return true;
/* Check if o is an instance of PatientRecordEntity or not
"null instanceof [type]" also returns false */
if (!(o instanceof PatientRecordEntity))
return false;
// typecast o to Complex so that we can compare data members
PatientRecordEntity c = (PatientRecordEntity) o;
// Compare the data members and return accordingly
return Double.compare(pid, c.pid) == 0
&& patient_db_ID.equals(c.patient_db_ID)
&& bed_number.equals(c.bed_number)
&& patient_race.equals(c.patient_race)
&& real_bed_number.equals(c.real_bed_number)
&& register_date.equals(c.register_date)
&& register_time.equals(c.register_time)
&& Double.compare(patient_age,c.patient_age)==0
&& Double.compare(patient_gender,c.patient_gender)==0
&& patient_IC.equals(c.patient_IC)
&& Double.compare(no_wounds,c.no_wounds)==0;
}
and this is my test in android test package:
#Test
public void addNewPatient() throws Exception {
PatientRecordEntity newPatient = new PatientRecordEntity();
newPatient.setPatient_db_ID("123456");
newPatient.setPatient_race("chines");
newPatient.setBed_number("123");
newPatient.setPatient_age(12);
int newRowId = 0;
newRowId = (int) patientDao.addNewPatient(newPatient);
expected_current_patient_record_entity = newPatient;
actual_current_patient_record_entity = patientDao.getPatientRecord("123456", "123");
if (expected_current_patient_record_entity.equals(actual_current_patient_record_entity)) {
assertTrue(true);
}else {
System.out.println("Not Equal");
assertTrue("The getPatientRecord test failed", false);
}
I want to write a loop in the test or in an equal method for when two objects aren't equal, gives me an error that which fields of these object aren't equal
I write the hard coded method. I declare one boolean to check equality inside equals function
public boolean equals(Object o) {
// If the object is compared with itself then return true
if (o == this)
return true;
/* Check if o is an instance of PatientRecordEntity or not
"null instanceof [type]" also returns false */
if (!(o instanceof PatientRecordEntity))
return false;
// typecast o to Complex so that we can compare data members
PatientRecordEntity c = (PatientRecordEntity) o;
boolean isEqual = true; //I assume these are equal
// Compare the data members and return accordingly
if (Double.compare(pid, c.pid) != 0) {
System.out.println("PID not Equal");
isEqual = false;
}
if (!patient_db_ID.equals(c.patient_db_ID)) {
System.out.println("Patient ID not Equal");
isEqual = false;
}
if (!bed_number.equals(c.bed_number)) {
System.out.println("Bed number not Equal");
isEqual = false;
}
if (!patient_race.equals(c.patient_race)) {
System.out.println("Patient Race not Equal");
isEqual = false;
}
if (!real_bed_number.equals(c.real_bed_number)) {
System.out.println("Real Bed number not Equal");
isEqual = false;
}
if (!register_date.equals(c.register_date)) {
System.out.println("Registger bed not Equal");
isEqual = false;
}
if (!register_time.equals(c.register_time)) {
System.out.println("Register time not Equal");
isEqual = false;
}
if (Double.compare(patient_age,c.patient_age) != 0) {
System.out.println("Patient age not Equal");
isEqual = false;
}
if (Double.compare(patient_gender,c.patient_gender) != 0) {
System.out.println("Patient gender not Equal");
isEqual = false;
}
if (!patient_IC.equals(c.patient_IC)) {
System.out.println("Patient IC not Equal");
isEqual = false;
}
if (Double.compare(no_wounds,c.no_wounds) != 0) {
System.out.println("no wounds not Equal");
isEqual = false;
}
return isEqual; }
I have this objects:
COSTOS Costos = new COSTOS(1781, 359.13, "BISAG.SUP.PUER.TRA.I", "67550T9AT00ZZ");
COSTOS Herramienta = new COSTOS(1795, 299.11, "BISAG.INF.PUER.TRA.I", "67960T2MT02ZZ");
And this is my class:
public class COSTOS implements Comparable<COSTOS>{
public int referencia;
public double monto;
public String descripcion;
public String NumeroParte;
//Constructor
//getters setters
Also, i implemented HashCode and equals:
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((NumeroParte == null) ? 0 : NumeroParte.hashCode());
result = prime * result + ((descripcion == null) ? 0 : descripcion.hashCode());
long temp;
temp = Double.doubleToLongBits(monto);
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + referencia;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
COSTOS other = (COSTOS) obj;
if (NumeroParte == null) {
if (other.NumeroParte != null)
return false;
} else if (!NumeroParte.equals(other.NumeroParte))
return false;
if (descripcion == null) {
if (other.descripcion != null)
return false;
} else if (!descripcion.equals(other.descripcion))
return false;
if (Double.doubleToLongBits(monto) != Double.doubleToLongBits(other.monto))
return false;
if (referencia != other.referencia)
return false;
return true;
}
How could i implement a method that could print all the attributes
that are not equals?
I tried to use "import java.util.Objects;" to use: "Objects.hash(referencia, monto, descripcion, NumeroParte);", so that may give me the results to print
First, your methods can be simplified by using the null-safe Objects helper methods added in Java 7:
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Objects.hashCode(this.NumeroParte);
result = prime * result + Objects.hashCode(this.descripcion);
result = prime * result + Double.hashCode(this.monto);
result = prime * result + this.referencia;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
COSTOS other = (COSTOS) obj;
return (Objects.equals(this.NumeroParte, other.NumeroParte)
&& Objects.equals(this.descripcion, other.descripcion)
&& Double.doubleToLongBits(this.monto) == Double.doubleToLongBits(other.monto)
&& this.referencia == other.referencia);
}
How could i implement a method that could print all the attributes that are not equals?
To print differences, do the same comparisons as the equals method:
public void printDifferences(COSTOS other) {
if (! Objects.equals(this.NumeroParte, other.NumeroParte))
System.out.println("Different NumeroParte: " + this.NumeroParte + " != " + other.NumeroParte);
if (! Objects.equals(this.descripcion, other.descripcion))
System.out.println("Different descripcion: " + this.descripcion + " != " + other.descripcion);
if (Double.doubleToLongBits(this.monto) != Double.doubleToLongBits(other.monto))
System.out.println("Different monto: " + this.monto + " != " + other.monto);
if (this.referencia != other.referencia)
System.out.println("Different referencia: " + this.referencia + " != " + other.referencia);
}
If I understand you requirement correctly, you want to print out the values of attributes which are not the same in 2 objects, then you can create a method as follows.
public void compareAttributes(COSTOS other) {
if (this.getMonto() != other.getMonto()) {
System.out.println("Not equal. This obj : " + this.getMonto()
+ " Other obj : " + other.getMonto());
}
// you can do the same for the remaining attributes.
}
EDIT:
As #Andreas, pointed out in the comments you should place this method in your COSTOS class itself so every object can be compared easily.
I need to add an object to a list only when the given list does not already contain a object with similar properties
List<Identifier> listObject; //list
Identifier i = new Identifier(); //New object to be added
i.type = "TypeA";
i.id = "A";
if(!listObject.contains(i)) { // check
listObject.add(i);
}
I tried contains() to have a check on the existing list. If the list already has an object say j with j.type = "TypeA" and j.id = "A", I don't want to add that to list.
Can you please help me achieve this by overriding equals or any solution that can do?
Implement equals() and hashCode() in your Identifier class.
If you don't want to perform a check before adding the element, you can change your listObject from List to Set. A Set is a collection that contains no duplicate elements.
Follows an example of implementation automatically created by Eclipse IDE:
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Identifier other = (Identifier) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
return true;
}
We all know that if equals method returns true, then two objects are equal.
Can anybody give an example where 2 objects have the same hash value but they are actually different?
I'm assuming you're familiar with the contract(s) associated with overriding equals() and hashCode(), and the implications of a collision-prone hashCode implementation. Given that, the following trivial example uses an object that holds two Integers and implements a very simple hashCode, and demonstrates how easy it is to have two objects that aren't equal but have the same hashCode. Providing a more sophisticated hashCode algorithm can alleviate this.
The output of running main is:
hashCodes: ih1: 6, ih2: 6
equals: false
Example code:
package example.stackoverflow;
public class IntHolder
{
private Integer primaryData;
private Integer secondaryData;
public IntHolder(Integer primaryData, Integer secondaryData)
{
this.primaryData = primaryData;
this.secondaryData = secondaryData;
}
#Override
public int hashCode()
{
return ((primaryData == null) ? 0 : primaryData.hashCode()) +
((secondaryData == null) ? 0 : secondaryData.hashCode());
}
#Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
IntHolder other = (IntHolder) obj;
if (primaryData == null)
{
if (other.primaryData != null)
return false;
}
else if (!primaryData.equals(other.primaryData))
return false;
if (secondaryData == null)
{
if (other.secondaryData != null)
return false;
}
else if (!secondaryData.equals(other.secondaryData))
return false;
return true;
}
public static void main(String[] args)
{
IntHolder ih1 = new IntHolder(1, 5);
IntHolder ih2 = new IntHolder(3, 3);
System.out.println("hashCodes: ih1: " + ih1.hashCode() + ", ih2: " + ih2.hashCode());
System.out.println("equals: " + ih1.equals(ih2));
}
}
For reference, Eclipse's auto-generated hashCode() for the IntHolder class is:
#Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result
+ ((primaryData == null) ? 0 : primaryData.hashCode());
result = prime * result
+ ((secondaryData == null) ? 0 : secondaryData.hashCode());
return result;
}
String str1="abcdef";
String str2="abcdfG";
They both have the same hashcode and equals method returns false.
public class Employee {
protected long employeeId;
public boolean equals(Object o){
if(o == null) return false;
if(!(o instanceof) Employee) return false;
Employee other = (Employee) o;
return this.employeeId == other.employeeId;
}
public int hashCode(){
return (int) this.employeeId;
}
}
In this example, we have overridden the equals method - two employees are equal when they will have same employee id.
If two Employee objects are equal, they will also have the same hash code.
Your Ans -
In this example, we also implemented the hash code - hashcode is the employeeId that is rounded down to an int. That means that many employee id's could result in the same hash code, but these Employee objects would still not be equal, since they don't have the same employee id.
I have two java user defined java objects, how can i make these two objects to return same references with case ignore
Sample code:
public class compare{
private String name;
private Integer number;
}
java.lang.String has a method for this:
myString.equalsIgnoreCase("MyStRiNg");
If this is not what you are looking for please be more specific.
You must override hashcode and equals to properly compare two objects. The following is an IDE generated hashCode and equals method.
class A
{
#Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((number == null) ? 0 : number.hashCode());
return result;
}
#Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
A other = (A) obj;
if (name == null)
{
if (other.name != null)
return false;
}
else if (!name.equalsIgnoreCase(other.name))
return false;
if (number == null)
{
if (other.number != null)
return false;
}
else if (!number.equals(other.number))
return false;
return true;
}
String name;
Integer number;
}