Hello,
I have simple test using a AbstractClass as MappedSuperClass and using the id to calculate the hashCode and using the equals method (Hibernate 5.0.7 / JPA):
Code:
@MappedSuperclass
public abstract class AbstractEntity implements Serializable {
private static final long serialVersionUID = -921930556963950805L;
@Id
@Column(name = "C_ID", unique = true, updatable = false, nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
protected Long id;
public Long getId() {
return this.id;
}
public void setId(final Long id) {
this.id = id;
}
/**
* Two entities are considered equal if they are of the same class and have the same ID.
* An entity that has no ID (i.e. it is not persistent yet) is only equal to itself.
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof AbstractEntity)) {
return false;
}
AbstractEntity other = (AbstractEntity) obj;
if (id == null) {
if (other.id != null) {
return false;
}
} else if (!id.equals(other.id)) {
return false;
}
return true;
}
/**
* Use the id to calculate the hashCode.
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
}
And implementing two classes that using the abstract class:
Code:
@Entity
@Table(name = "T_ADDRESS")
public class Address extends AbstractEntity implements Serializable {
private static final long serialVersionUID = -2096844448338376419L;
/**
* The associated <code>User</code> (handles a bi-directional relationship).
*/
@ManyToOne
@JoinColumn(name = "JOIN_COL_ADDRESS_USER")
private User user;
public Address() {
}
public User getUser() {
return this.user;
}
/**
* The relationship is bidirectional,
* the relationship has to be removed manually on the other side.
*/
public void addUser(@NotNull final User user) {
this.user = user;
user.internalAddAddress(this);
}
/**
* The relationship is bidirectional,
* the relationship has to be removed manually on the other side.
*/
public void removeUser() {
if (this.user != null) {
this.user.internalRemoveAddress(this);
this.user = null;
}
}
}
and
Code:
@Entity
@Table(name = "T_USER")
public class User extends AbstractEntity implements Serializable {
private static final long serialVersionUID = 4283786193325586932L;
/**
* The <code>Address</code>es of this user (handles bi-directional
* relationship).
*/
@OneToMany(mappedBy = "user", cascade = { CascadeType.ALL }, orphanRemoval = true)
private final Set<Address> addresses = new LinkedHashSet<>();
public User() {
}
// _____________________________________________________________
// Address handling.
// -------------------------------------------------------------
public Set<Address> getAddresses() {
return Collections.unmodifiableSet(this.addresses);
}
public void addAddress(final Address address) {
address.addUser(this);
}
public void removeAddress(final Address address) {
address.removeUser();
}
/**
* The relationship is
* bidirectional, the relationship has to be added manually on the other
* side.
*/
protected void internalAddAddress(final Address address) {
this.addresses.add(address);
}
/**
* The relationship is
* bidirectional, the relationship has to be removed manually on the other
* side.
*/
public void internalRemoveAddress(final Address address) {
[color=#FF0000]this.addresses.remove(address);[/color]
}
}
The user handles a OneToMany Relationship to the Address.
Adding a Address to Users collection works.
User user = new User();
Address address = new Address();
user.addAddress(address);
entityManager.persist(address);
entityManager.persist(user);
But removing a address from the addresses collection does not work.
The method internalRemoveAddress is invoked and the address should be invoked from the collection, but it does not work.
The two affected elements (in collection and the parameter) are equal using 'collectionAddressElement.equals(address)'
But if I change the attribute id in the equals and hashcode method with a nother value like a uuid the remove works fine.
Where is my mistake?