Reputation: 1180
It is recommended to implement equals()
and hashcode()
for the entities that are detached and reattached frequently. Especially if we are using a set or collections.
I haven't seen any examples for relationships, so how would we implement those methods correctly in the example below? And do we also need a derived set class that overrides the standard set methods?
/**
* A component which marks a {@link com.artemis.Entity} as a chunk and stores its most valuable information.
*/
@Entity
@Table(name = "chunk")
@Access(value = AccessType.FIELD)
public class Chunk extends HibernateComponent{
public int x;
public int y;
public Date createdOn;
@OneToMany(fetch = FetchType.EAGER)
@JoinTable(name = "chunk_identity", joinColumns = @JoinColumn(name = "identity_id"), inverseJoinColumns = @JoinColumn(name = "id"), inverseForeignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
public Set<Identity> inChunk = new LinkedHashSet<>();
@Transient
public Set<ChunkLoader> loadedBy = new LinkedHashSet<>();
public Chunk() {}
public Chunk(int x, int y, Date createdOn) {
this.x = x;
this.y = y;
this.createdOn = createdOn;
}
}
/**
* Represents a ID of a {@link com.artemis.Entity} which is unique for each entity and mostly the database id
*/
@Entity
@Table(name = "identity")
@Access(AccessType.FIELD)
public class Identity extends Component {
@Id public long id;
public String tag;
public String typeID;
public Identity() {}
public Identity(long id, String tag, String typeID) {
this.id = id;
this.tag = tag;
this.typeID = typeID;
}
}
Upvotes: 0
Views: 424
Reputation: 16430
You should always implement equals and hashCode for entities, preferrably based on the primary key or if available, based on a natural key. The only thing you have to keep in mind is, that if you add an entity to a hash set or as key to a hash map, and the equals/hashCode implementations are based on the primary key, you might get into trouble if no primary key is set on the entity that is added. If the primary key is set during flushing, the hash code of that entity would change which breaks hash sets and hash maps as they require the hash code to be stable. To make this work I usually suggest to rebuild the hash sets or hash maps if really needed. I usually use an implementation like this:
@MappedSuperclass
public class LongSequenceEntity implements Serializable {
private Long id;
public LongSequenceEntity() {
}
public LongSequenceEntity(Long id) {
this.id = id;
}
@Id
@GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (getId() == null || !(o instanceof LongSequenceEntity)) {
return false;
}
return getId().equals(((LongSequenceEntity) o).getId());
}
@Override
public int hashCode() {
return getId() != null ? getId().hashCode() : 0;
}
}
Upvotes: 1
Reputation: 612
Just like Louis Wasserman said in a previous post - "You should implement equals and hashCode for objects you write which contain collections"
There is also a way to generate it automatically.
Depending on what IDE you are using it can generate equals() and hashcode() for you.
In Intellij IDE you can right click inside of the code -> Choose option "Generate" and click on "equals() and hashcode()"
You can see more about intellij option there: https://www.jetbrains.com/help/idea/generating-code.html#generate-getters-setters
Upvotes: 1
Reputation: 198211
The objects of your own types that you are putting into collections should have equals
and hashCode
implemented. That's exactly the time when it's most important to implement equals
and hashCode
.
You do not need to -- you should not -- implement equals
and hashCode
for collection objects, even if they contain other objects.
You should implement equals
and hashCode
for objects you write which contain collections, and in the implementation of those methods, you should use the collection objects' built-in equals
and hashCode
methods.
Upvotes: 2