The Problem with PersistentBag
is that it violates the Collections API equals()
contract, which breaks unit test assertions via AssertJ's containsExactlyInAnyOrder()
. Hibernate also has different wrapper implementations such as PersistentList
, is there a way to force Hibernate (version 5.6.7) to use those instead of PersistentBag
?
@Entity
data class AnalysisType(
@Id
name: String,
@Column(name = "reference_type")
@OneToMany(fetch = LAZY, cascade = [])
val referenceTypes: List<ReferenceType>
)
@Entity
data class ReferenceType(
@Id
val id: Long,
@Column
val name: String
)
CodePudding user response:
I think there's something wrong with the unit tests. Comparing two collections using an equals doesn't seem the right approach. In particular, when using unordered lists, elements might not always be in the same order.
You also need to make sure that you've implemented the correct hashcode/equals for the entities. In java, for ReferenceType, it should look like:
@Override
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( !( o instanceof ReferenceType ) ) {
return false;
}
ReferenceType rt = (ReferenceType) o;
return Objects.equals( name, rt.name );
}
@Override
public int hashCode() {
return Objects.hash( name );
}
That said, if you want to have a PersistentList, the mapping needs to reflect an ordered list. You can achieve this using @OrderColumn
:
@Entity(name = "Person")
public static class Person {
@Id
private Long id;
@OneToMany(cascade = CascadeType.ALL)
@OrderColumn
private List<Phone> phones = new ArrayList<>();
//Getters and setters are omitted for brevity
}
You can find more in the Hibernate ORM documentation in the section about collections of entities.
CodePudding user response:
If you are using containsExactlyInAnyOrder
from assertj the order of the elements does not matter. You can check for duplicates. If the PersistentBag
contains the same element twice you should use containsOnly
which does not care about the order and is ignoring duplicates. The equals
method on the PersistentBag
should not matter too because the contains...
assertions in assertj are comparing element by element for the collections.
It looks like they may be sth wrong in your tests. Can you post assertj message?