JPA,从实体的哈希集中删除对象需要调用getter才能使持久性起作用

时间:2019-04-21 14:50:35

标签: java jpa entity persistence getter

当我尝试从哈希集中删除对象时,我试图保留实体所做的更改。我不明白为什么我的前两个版本不起作用第三个版本不起作用

在第五次测试中,我更新了实体

在第六次测试中,我尝试检查前一次测试的更新是否仍然有效。三种版本的“删除”方法对此测试产生不同的结果。前两个无效,而第三个无效。

测试设置

  @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");
  }

第五项测试,该测试适用于每个版本的remove方法

@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));
  }

第六次测试使用“删除”方法的前两个版本失败。 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);
  }

第二版的remove方法依赖于Student类中的第二版removeGuest方法

  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);
  }

0 个答案:

没有答案