/**
   * test for issue 635: NullPointerException occuring for Object typed version fields. Employee has
   * a write lock (version) field of type Integer The NullPointerException is thrown when comparing
   * versions in ObjectChangeSet#compareWriteLockValues
   */
  public void testCreateEmployeeWithFlush() {
    EntityManager em = createEntityManager("fieldaccess");
    Project project1, project2;
    Employee employee;

    try {
      beginTransaction(em);
      employee = ModelExamples.employeeExample1();
      em.persist(employee);

      // first flush: Employee is written to the database
      Query query = em.createNamedQuery("findFieldAccessProjectByName");
      query.setParameter("name", "Farmer effecency evaluations");
      project1 = (Project) query.getSingleResult();
      employee.getProjects().add(project1);

      // second flush: Employee is modified, but
      // no update to EMPLOYEE table; only join table entry is written
      query = em.createNamedQuery("findFieldAccessProjectByName");
      query.setParameter("name", "Feline Demographics Assesment");
      project2 = (Project) query.getSingleResult();
      employee.getProjects().add(project2);

      // third flush: Employee is modified, but
      // no update to EMPLOYEE table; only join table entry is written
      // A NullPointerException in ObjectChangeSet#compareWriteLockValues
      commitTransaction(em);
    } catch (RuntimeException e) {
      if (isTransactionActive(em)) {
        rollbackTransaction(em);
      }
      closeEntityManager(em);
      throw e;
    }
  }
  /**
   * test: updating the version field with the in-memory value. This should be allowed; there's no
   * change for TopLink to detect this.
   */
  public void testVersionUpdateWithCorrectValue() {
    EntityManager em = createEntityManager("fieldaccess");
    Employee employee;

    try {
      beginTransaction(em);
      employee = ModelExamples.employeeExample1();
      em.persist(employee);
      commitTransaction(em);

      beginTransaction(em);
      employee.setVersion(1);
      commitTransaction(em);
    } catch (RuntimeException re) {
      if (isTransactionActive(em)) {
        rollbackTransaction(em);
      }
      closeEntityManager(em);
      throw re;
    }
  }
  /**
   * test: updating the version field with value != in-memory value. This should throw an
   * OptimisticLockException
   */
  public void testVersionUpdateWithIncorrectValue() {
    EntityManager em = createEntityManager("fieldaccess");
    Employee employee;

    try {
      beginTransaction(em);
      employee = ModelExamples.employeeExample1();
      em.persist(employee);
      commitTransaction(em);

      beginTransaction(em);
      Employee employee1 = em.find(Employee.class, employee.getId());
      employee1.setVersion(2);
      commitTransaction(em);
      fail("updating object version with wrong value didn't throw exception");
    } catch (PersistenceException pe) {
      // expected behavior
    } catch (Exception exception) {
      Throwable persistenceException = exception;
      // Remove an wrapping exceptions such as rollback, runtime, etc.
      while (persistenceException != null
          && !(persistenceException instanceof OptimisticLockException)) {
        // In the server this is always a rollback exception, need to get nested exception.
        persistenceException = persistenceException.getCause();
      }
      if (persistenceException instanceof OptimisticLockException) {
        return;
      } else {
        fail(
            "updating object version with wrong value threw a wrong exception: "
                + exception.getMessage());
      }
    } finally {
      if (isTransactionActive(em)) {
        rollbackTransaction(em);
      }
      closeEntityManager(em);
    }
  }