Я пытаюсь persit изменения, которые я делаю в сущности , когда я пытаюсь удалить объект из Hashset .Я не понимаю, почему мои первые две версии не работают , а - третья.
В пятом тесте я обновляю сущность
В шестом тесте я пытаюсь проверить, действует ли обновление с предыдущего теста.Три версии методов удаления дают разные результаты для этого теста.Первые два не работают, а третий работает.
Настройка тестов
@Inject
private InvitationManagerBean invitationManagerBean;
private Student host1;
private Attendant guest;
private int id;
private Attendant guest2;
private Attendant guest3;
@PersistenceContext
private EntityManager entityManager;
@Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class)
.addPackage(InvitationManagerBean.class.getPackage())
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")
.addAsManifestResource(new ClassLoaderAsset("META-INF/persistence.xml"), "persistence.xml");
}
@Before
public void initialize() {
host1 = new Student("john", "wick", "johnwick@gmail.com");
guest = new Attendant("tony", "iommi");
guest2 = new Attendant("marge", "simpson");
guest3 = new Attendant("homer", "simpson");
}
Пятый тест, Этот тест работает с каждой версией метода удаления
@Test
@InSequence(5)
public void removeTest() throws StudentDoesNotExistException, GuestDoesNotExistException {
//query
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Student> criteria = builder.createQuery(Student.class);
Root<Student> root = criteria.from(Student.class);
criteria.select(root).where(builder.equal(root.get("mail"), host1.getMail()));
TypedQuery<Student> query = entityManager.createQuery(criteria);
Student res;
res = query.getSingleResult();
assertEquals(3, res.getGuests().size());
assertTrue(res.hasInvited(guest));
assertTrue(res.hasInvited(guest2));
assertTrue(res.hasInvited(guest3));
assertTrue(invitationManagerBean.remove(res, "homer", "simpson"));
assertEquals(2, res.getGuests().size());
assertTrue(res.hasInvited(guest));
assertTrue(res.hasInvited(guest2));
assertFalse(res.hasInvited(guest3));
}
Шестой тест терпит неудачу с первыми двумя версиями метода "remove" .Сбой assertEquals, потому что имеет значение 3 вместо 2 , что означает, что операция удаления из пятого теста не работает
@Test
@InSequence(6)
public void removeNotExistTest() throws StudentDoesNotExistException, GuestDoesNotExistException {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Student> criteria = builder.createQuery(Student.class);
Root<Student> root = criteria.from(Student.class);
criteria.select(root).where(builder.equal(root.get("mail"), host1.getMail()));
TypedQuery<Student> query = entityManager.createQuery(criteria);
Student res;
res = query.getSingleResult();
assertEquals(2, res.getGuests().size()); //IS 3 WHEN FAILS
}
первая версия метода удаления и первый метод removeGuest (), на который он опирается .
public boolean remove(Student host, String name, String lastName) throws StudentDoesNotExistException, GuestDoesNotExistException{
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Student> criteria = builder.createQuery(Student.class);
Root<Student> root = criteria.from(Student.class);
criteria.select(root).where(builder.equal(root.get("mail"), host.getMail()));
TypedQuery<Student> query = entityManager.createQuery(criteria);
Student s;
Attendant guest;
guest = new Attendant(name, lastName);
try {
s = query.getSingleResult();
} catch (NoResultException e) {
throw new StudentDoesNotExistException("the host does no exist");
} catch(Exception e){
return false;
}
if(!s.hasInvited(guest)) {
throw new GuestDoesNotExistException("tried to remove a guest that has not been invited");
}
s.removeGuest(guest); //CHANGE IS HERE
return true;
public void removeGuest(Attendant a) {
guests.remove(a);
}
вторая версия метода удаления опирается на вторую версию метода removeGuest в классе Student:
public void removeGuest(Attendant a) {
getGuests().remove(a);
}
третья версия метода удаления ...
s.getGuests().removeIf(v -> v.getName().equals(name) && v.getLastName().equals(lastName));
... опирается на следующий метод removeGuest ():
public void removeGuest(Attendant a) {
guests.remove(a);
}
Ученик класса
@Entity
@DiscriminatorValue(value = "S")
public class Student extends Attendant implements Serializable {
@Pattern(regexp = "\\d{10}+", message = "Invalid creditCardNumber")
private String creditCard;
@OneToMany(cascade = {CascadeType.REMOVE, CascadeType.MERGE, CascadeType.PERSIST}, fetch = FetchType.LAZY)
private Set<Attendant> guests;
public Set<Attendant> getGuests() {
return guests;
}
public Student() {
super();
}
public Student(String name, String lastName, String mail) {
super(name, lastName);
this.mail = mail;
guests = new HashSet<>();
}
public String getCreditCard() {
return creditCard;
}
public void setCreditCard(String creditCard) {
this.creditCard = creditCard;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
Student student = (Student) o;
return Objects.equals(mail, student.mail) && Objects.equals(creditCard, student.creditCard);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), creditCard, mail);
}
@Override
public String toString() {
return "Student{" +
"creditCard='" + creditCard + '\'' +
"} " + super.toString();
}
public void addGuest(Attendant a) {
guests.add(a);
}
public void removeGuest(Attendant a) {
guests.remove(a);
}
public boolean hasInvited(Attendant a) {
return guests.contains(a);
}
}
Оператор равно и хэш-код
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Attendant attendant = (Attendant) o;
return name.equals(attendant.name) &&
lastName.equals(attendant.lastName) ;
}
@Override
public int hashCode() {
return Objects.hash(name, lastName);
}