I have a quite simple problem, yet a very weird behaviour on which a Set
does not delete elements on true
predicates for some reason.
The entities (for reference only, as this does not have anything to do with the set item - or shouldn't):
@Data
@MappedSuperclass
@EqualsAndHashCode(of = "uuid")
public abstract class Model<ID> {
@Id
@GeneratedValue
protected ID id;
protected UUID uuid; // Hybrid model
@PrePersist
private void onPersisting() {
uuid = UUID.randomUUID();
}
}
@Data
@Entity
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true, of = "name")
@Table(uniqueConstraints = @UniqueConstraint(name = "scope_name", columnNames = "name"))
public class Scope extends Model<Long> {
private String name;
public Scope(UUID uuid) {
this.uuid = uuid;
}
public Scope(String name) {
this.name = name;
}
}
@Data
@Entity
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true, of = "name")
@Table(uniqueConstraints = @UniqueConstraint(name = "role_name", columnNames = "name"))
public class Role extends Model<Long> {
private String name;
@ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
@JoinTable(name = "role_scopes", joinColumns = @JoinColumn(name = "role_id"), inverseJoinColumns = @JoinColumn(name = "scope_id"))
private Set<Scope> scopes = new HashSet<>();
public Role(UUID uuid, Scope... scopes) {
this.scopes = Stream.of(scopes).collect(Collectors.toSet());
this.uuid = uuid;
}
public Role(String name, Scope... scopes) {
this.scopes = Stream.of(scopes).collect(Collectors.toSet());
this.name = name;
}
}
The following snippet, called within a JUnit test case, does not delete the set elements (simplified for readability):
@Transactional
public Role create(Role role) {
role.getScopes().removeIf(unused -> true); // <----
return role;
}
For some reason, that snippet does work:
Set<String> strings = new HashSet<>();
strings.add("FOO");
strings.add("BAR");
strings.removeIf(unused -> true);
What's going on here?
It is because of overridden equals
and hashCode
that is done by @Data
annotation on your Scope
class. If you remove it or replace with @Getter @Setter
it will work
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.