/*******************************************************************************
 * Copyright (c) 2005, 2009 SAP. All rights reserved.
 * This program and the accompanying materials are made available under the 
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     SAP - initial API and implementation
 ******************************************************************************/

package org.eclipse.persistence.testing.tests.wdf.jpa1.entitymanager;

import java.sql.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.TransactionRequiredException;

import org.eclipse.persistence.testing.framework.wdf.Bugzilla;
import org.eclipse.persistence.testing.framework.wdf.JPAEnvironment;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Cubicle;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Department;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Employee;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Project;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Review;
import org.eclipse.persistence.testing.models.wdf.jpa1.node.Node;
import org.eclipse.persistence.testing.tests.wdf.jpa1.JPA1Base;
import org.junit.Test;

public class TestFlush extends JPA1Base {

    /*
     * For any entity Y referenced by a relationship from X, where the relationship to Y has not been annotated with the cascade
     * element value cascade=PERSIST or cascade=ALL: <p> If Y is new or removed, an IllegalStateException will be thrown by the
     * flush operation (and the transaction rolled back) or the transaction commit will fail.
     */
    @Test
    public void testRelationshipToNew() {
        JPAEnvironment env = getEnvironment();
        EntityManager em = env.getEntityManager();
        try {
            // case 1: direct relationship Employee -> Cubicle (new) - 1:1
            Department dep = new Department(1, "dep");
            Employee emp1 = new Employee(2, "first", "last", dep);
            Cubicle cub1 = new Cubicle(new Integer(3), new Integer(3), "color", emp1);
            emp1.setCubicle(cub1);
            env.beginTransaction(em);
            em.persist(dep);
            em.persist(emp1);
            boolean flushFailed = false;
            try {
                em.flush();
            } catch (IllegalStateException e) {
                // $JL-EXC$ this is expected behavior
                flushFailed = true;
                verify(env.isTransactionMarkedForRollback(em),
                        "IllegalStateException during flush did not mark transaction for rollback");
                env.rollbackTransactionAndClear(em);
            }
            try {
                if (env.isTransactionActive(em)) {
                    env.commitTransactionAndClear(em);
                }
            } catch (RuntimeException e) {
                if (!checkForIllegalStateException(e)) {
                    throw e;
                }
                flushFailed = true;
            }
            verify(!env.isTransactionActive(em), "Transaction still active");
            verify(flushFailed, "flush succeeded although there is a relation to an unmanaged entity");
            // case 2: direct relationship Employee -> Project (new) - n:m
            dep = new Department(4, "dep");
            emp1 = new Employee(5, "first", "last", dep);
            Project proj = new Project("project");
            Set<Project> emp1Projects = new HashSet<Project>();
            emp1Projects.add(proj);
            emp1.setProjects(emp1Projects);
            Set<Employee> projEmployees = new HashSet<Employee>();
            projEmployees.add(emp1);
            proj.setEmployees(projEmployees);
            env.beginTransaction(em);
            em.persist(dep);
            em.persist(emp1);
            flushFailed = false;
            try {
                em.flush();
            } catch (IllegalStateException e) {
                // $JL-EXC$ this is expected behavior
                flushFailed = true;
                verify(env.isTransactionMarkedForRollback(em),
                        "IllegalStateException during flush did not mark transaction for rollback");
                env.rollbackTransactionAndClear(em);
            }
            try {
                if (env.isTransactionActive(em)) {
                    env.commitTransactionAndClear(em);
                }
            } catch (RuntimeException e) {
                if (!checkForIllegalStateException(e)) {
                    throw e;
                }
                flushFailed = true;
            }
            verify(!env.isTransactionActive(em), "Transaction still active");
            verify(flushFailed, "flush succeeded although there is a relation to an unmanaged entity");
            // case 3: indirect relationship Employee -> Project -> Employee (new)
            dep = new Department(7, "dep");
            emp1 = new Employee(8, "first1", "last1", dep);
            Employee emp2 = new Employee(9, "first2", "last2", dep);
            proj = new Project("project");
            emp1Projects = new HashSet<Project>();
            emp1Projects.add(proj);
            emp1.setProjects(emp1Projects);
            Set<Project> emp2Projects = new HashSet<Project>();
            emp2Projects.add(proj);
            emp2.setProjects(emp2Projects);
            projEmployees = new HashSet<Employee>();
            projEmployees.add(emp1);
            projEmployees.add(emp2);
            proj.setEmployees(projEmployees);
            env.beginTransaction(em);
            em.persist(dep);
            em.persist(emp1);
            em.persist(proj);
            flushFailed = false;
            try {
                em.flush();
            } catch (IllegalStateException e) {
                // $JL-EXC$ this is expected behavior
                flushFailed = true;
                verify(env.isTransactionMarkedForRollback(em),
                        "IllegalStateException during flush did not mark transaction for rollback");
                env.rollbackTransactionAndClear(em);
            }
            try {
                if (env.isTransactionActive(em)) {
                    env.commitTransactionAndClear(em);
                }
            } catch (RuntimeException e) {
                if (!checkForIllegalStateException(e)) {
                    throw e;
                }
                flushFailed = true;
            }
            verify(!env.isTransactionActive(em), "Transaction still active");
            verify(flushFailed, "flush succeeded although there is a relation to an unmanaged entity");
        } finally {
            closeEntityManager(em);
        }
    }

    /*
     * For any entity Y referenced by a relationship from X, where the relationship to Y has not been annotated with the cascade
     * element value cascade=PERSIST or cascade=ALL: <p> If Y is new or removed, an IllegalStateException will be thrown by the
     * flush operation (and the transaction rolled back) or the transaction commit will fail.
     */
    @SuppressWarnings("unchecked")
    @Test
    @Bugzilla(bugid=317760)
    public void testRelationshipToRemoved() {
        JPAEnvironment env = getEnvironment();
        EntityManager em = env.getEntityManager();
        try {
            // case 1: direct relationship Employee -> Cubicle (FOR_DELETE) - 1:1
            Department dep = new Department(101, "dep");
            Employee emp1 = new Employee(102, "first", "last", dep);
            Cubicle cub1 = new Cubicle(new Integer(103), new Integer(103), "color", emp1);
            emp1.setCubicle(cub1);
            env.beginTransaction(em);
            em.persist(dep);
            em.persist(emp1);
            em.persist(cub1);
            env.commitTransactionAndClear(em);
            
            env.beginTransaction(em);
            emp1 = em.find(Employee.class, new Integer(emp1.getId()));
            cub1 = em.find(Cubicle.class, cub1.getId());
            cub1.setEmployee(null); // added as suggested by Tom
            em.remove(cub1);
            boolean flushOrCommmitFailed = false;
            try {
                em.flush();
            } catch (IllegalStateException e) {
                // $JL-EXC$ this is expected behavior
                flushOrCommmitFailed = true;
                verify(env.isTransactionMarkedForRollback(em),
                        "IllegalStateException during flush did not mark transaction for rollback");
                env.rollbackTransactionAndClear(em);
            }
            try {
                if (env.isTransactionActive(em)) {
                    env.commitTransactionAndClear(em);
                }
            } catch (RuntimeException e) {
                if (!checkForIllegalStateException(e)) {
                    throw e;
                }
                flushOrCommmitFailed = true;
            }
            verify(!env.isTransactionActive(em), "Transaction still active");
            verify(flushOrCommmitFailed, "flush succeeded although there is a relation to a removed entity");
            em.clear();
            // case 2: direct relationship Employee -> Project (FOR_DELETE) - n:m
            dep = new Department(104, "dep");
            emp1 = new Employee(105, "first", "last", dep);
            Project proj = new Project("project");
            Set<Project> emp1Projects = new HashSet<Project>();
            emp1Projects.add(proj);
            emp1.setProjects(emp1Projects);
            Set<Employee> projEmployees = new HashSet<Employee>();
            projEmployees.add(emp1);
            proj.setEmployees(projEmployees);
            env.beginTransaction(em);
            em.persist(proj);
            em.persist(dep);
            em.persist(emp1);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            emp1 = em.find(Employee.class, new Integer(emp1.getId()));
            proj = em.find(Project.class, proj.getId());
            emp1.getProjects().size();
            em.remove(proj);
            flushOrCommmitFailed = false;
            try {
                em.flush();
            } catch (IllegalStateException e) {
                // $JL-EXC$ this is expected behavior
                flushOrCommmitFailed = true;
                verify(env.isTransactionMarkedForRollback(em),
                        "IllegalStateException during flush did not mark transaction for rollback");
                env.rollbackTransactionAndClear(em);
            }
            try {
                if (env.isTransactionActive(em)) {
                    env.commitTransactionAndClear(em);
                }
            } catch (RuntimeException e) {
                if (!checkForIllegalStateException(e)) {
                    throw e;
                }
                flushOrCommmitFailed = true;
            }
            verify(!env.isTransactionActive(em), "Transaction still active");
            verify(flushOrCommmitFailed, "flush succeeded although there is a relation to an unmanaged entity");
            em.clear();
            // case 3: indirect relationship Employee -> Project -> Employee (FOR_DELETE)
            dep = new Department(107, "dep");
            emp1 = new Employee(108, "first1", "last1", dep);
            Employee emp2 = new Employee(109, "first2", "last2", dep);
            proj = new Project("project");
            emp1Projects = new HashSet<Project>();
            emp1Projects.add(proj);
            emp1.setProjects(emp1Projects);
            Set<Project> emp2Projects = new HashSet<Project>();
            emp2Projects.add(proj);
            emp2.setProjects(emp2Projects);
            projEmployees = new HashSet<Employee>();
            projEmployees.add(emp1);
            projEmployees.add(emp2);
            proj.setEmployees(projEmployees);
            env.beginTransaction(em);
            em.persist(proj);
            em.persist(dep);
            em.persist(emp1);
            em.persist(emp2);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            emp1 = em.find(Employee.class, new Integer(emp1.getId()));
            emp2 = em.find(Employee.class, new Integer(emp2.getId()));
            proj = em.find(Project.class, proj.getId());
            emp1.getProjects().size();
            proj.getEmployees().size();
            em.remove(emp2);
            flushOrCommmitFailed = false;
            try {
                em.flush();
            } catch (IllegalStateException e) {
                // $JL-EXC$ this is expected behavior
                flushOrCommmitFailed = true;
                verify(env.isTransactionMarkedForRollback(em),
                        "IllegalStateException during flush did not mark transaction for rollback");
                env.rollbackTransactionAndClear(em);
            }
            try {
                if (env.isTransactionActive(em)) {
                    env.commitTransactionAndClear(em);
                }
            } catch (RuntimeException e) {
                if (!checkForIllegalStateException(e)) {
                    throw e;
                }
                flushOrCommmitFailed = true;
            }
            verify(!env.isTransactionActive(em), "Transaction still active");
            verify(flushOrCommmitFailed, "flush succeeded although there is a relation to an unmanaged entity");
            em.clear();
            // case 1b: direct relationship Employee -> Cubicle (DELETE_EXECUTED) - 1:1
            dep = new Department(111, "dep");
            emp1 = new Employee(112, "first", "last", dep);
            cub1 = new Cubicle(new Integer(113), new Integer(112), "color", emp1);
            env.beginTransaction(em);
            em.persist(dep);
            em.persist(emp1);
            em.persist(cub1);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            emp1 = em.find(Employee.class, new Integer(emp1.getId()));
            cub1 = em.find(Cubicle.class, cub1.getId());
            em.remove(cub1);
            em.flush();
            emp1.setCubicle(cub1);
            flushOrCommmitFailed = false;
            try {
                em.flush();
            } catch (IllegalStateException e) {
                // $JL-EXC$ this is expected behavior
                flushOrCommmitFailed = true;
                verify(env.isTransactionMarkedForRollback(em),
                        "IllegalStateException during flush did not mark transaction for rollback");
                env.rollbackTransactionAndClear(em);
            }
            try {
                if (env.isTransactionActive(em)) {
                    env.commitTransactionAndClear(em);
                }
            } catch (RuntimeException e) {
                if (!checkForIllegalStateException(e)) {
                    throw e;
                }
                flushOrCommmitFailed = true;
            }
            verify(!env.isTransactionActive(em), "Transaction still active");
            verify(flushOrCommmitFailed, "flush succeeded although there is a relation to an unmanaged entity");
            em.clear();
            // case 2b: direct relationship Employee -> Project (DELETE_EXECUTED) - n:m
            dep = new Department(114, "dep");
            emp1 = new Employee(115, "first", "last", dep);
            proj = new Project("project");
            env.beginTransaction(em);
            em.persist(dep);
            em.persist(emp1);
            em.persist(proj);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            emp1 = em.find(Employee.class, new Integer(emp1.getId()));
            proj = em.find(Project.class, proj.getId());
            em.remove(proj);
            em.flush();
            emp1Projects = new HashSet<Project>();
            emp1Projects.add(proj);
            emp1.setProjects(emp1Projects);
            projEmployees = new HashSet<Employee>();
            projEmployees.add(emp1);
            proj.setEmployees(projEmployees);
            flushOrCommmitFailed = false;
            try {
                em.flush();
            } catch (IllegalStateException e) {
                // $JL-EXC$ this is expected behavior
                flushOrCommmitFailed = true;
                verify(env.isTransactionMarkedForRollback(em),
                        "IllegalStateException during flush did not mark transaction for rollback");
                env.rollbackTransactionAndClear(em);
            }
            try {
                if (env.isTransactionActive(em)) {
                    env.commitTransactionAndClear(em);
                }
            } catch (RuntimeException e) {
                if (!checkForIllegalStateException(e)) {
                    throw e;
                }
                flushOrCommmitFailed = true;
            }
            verify(!env.isTransactionActive(em), "Transaction still active");
            verify(flushOrCommmitFailed, "flush succeeded although there is a relation to an unmanaged entity");
            em.clear();
            // case 3b: indirect relationship Employee -> Project -> Employee (DELETE_EXECUTED)
            dep = new Department(117, "dep");
            emp1 = new Employee(118, "first1", "last1", dep);
            emp2 = new Employee(119, "first2", "last2", dep);
            proj = new Project("project");
            emp1Projects = new HashSet<Project>();
            emp1Projects.add(proj);
            emp1.setProjects(emp1Projects);
            projEmployees = new HashSet<Employee>();
            projEmployees.add(emp1);
            proj.setEmployees(projEmployees);
            env.beginTransaction(em);
            em.persist(proj);
            em.persist(dep);
            em.persist(emp1);
            em.persist(emp2);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            emp1 = em.find(Employee.class, new Integer(emp1.getId()));
            emp2 = em.find(Employee.class, new Integer(emp2.getId()));
            proj = em.find(Project.class, proj.getId());
            emp1.getProjects().size();
            projEmployees = proj.getEmployees();
            projEmployees.size();
            em.remove(emp2);
            em.flush();
            emp2Projects = new HashSet<Project>();
            emp2Projects.add(proj);
            emp2.setProjects(emp2Projects);
            projEmployees.add(emp2);
            flushOrCommmitFailed = false;
            try {
                em.flush();
            } catch (IllegalStateException e) {
                // $JL-EXC$ this is expected behavior
                flushOrCommmitFailed = true;
                verify(env.isTransactionMarkedForRollback(em),
                        "IllegalStateException during flush did not mark transaction for rollback");
                env.rollbackTransactionAndClear(em);
            }
            try {
                if (env.isTransactionActive(em)) {
                    env.commitTransactionAndClear(em);
                }
            } catch (RuntimeException e) {
                if (!checkForIllegalStateException(e)) {
                    throw e;
                }
                flushOrCommmitFailed = true;
            }
            verify(!env.isTransactionActive(em), "Transaction still active");
            verify(flushOrCommmitFailed, "flush succeeded although there is a relation to an unmanaged entity");
            em.clear();
        } finally {
            closeEntityManager(em);
        }
    }

    /**
     * This test checks a special case that can occur with lazily loaded relationships:
     * <ul>
     * <li>Read Project proj1 and remove it.</li>
     * <li>Read Employee emp1 with relationship to proj1 (lazy loading).</li>
     * <li>Assign the set of emp1's projects to a new employee emp2 (forces implicit loading on flush).</li>
     * <li>Flush -> IllegalStateException expected because of relation emp2 -> proj1 (removed).</li>
     * </ul>
     */
    @Test
    @Bugzilla(bugid=317760)
    public void testRelationshipToRemovedLazy() {
        JPAEnvironment env = getEnvironment();
        EntityManager em = env.getEntityManager();
        try {
            // case 1: explicit flush
            Department dep = new Department(201, "dep");
            Employee emp1 = new Employee(202, "first", "last", dep);
            Project proj = new Project("project");
            Set<Project> emp1Projects = new HashSet<Project>();
            emp1Projects.add(proj);
            emp1.setProjects(emp1Projects);
            Set<Employee> projEmployees = new HashSet<Employee>();
            projEmployees.add(emp1);
            proj.setEmployees(projEmployees);
            env.beginTransaction(em);
            em.persist(proj);
            em.persist(dep);
            em.persist(emp1);
            env.commitTransactionAndClear(em);
            
            env.beginTransaction(em);
            dep = em.find(Department.class, new Integer(dep.getId()));
            proj = em.find(Project.class, proj.getId());
            em.remove(proj);
            emp1 = em.find(Employee.class, new Integer(emp1.getId()));
            // copy all projects from emp1 to emp2 with out actually touching them
            Employee emp2 = new Employee(203, "aaa", "bbb", dep);
            proj.addEmployee(emp2); // added as suggested by Tom
            emp2.setProjects(emp1.getProjects());
            em.persist(emp2);
            boolean flushFailed = false;
            try {
                em.flush();
            } catch (IllegalStateException e) {
                // $JL-EXC$ this is expected behavior
                flushFailed = true;
                verify(env.isTransactionMarkedForRollback(em),
                        "IllegalStateException during flush did not mark transaction for rollback");
                env.rollbackTransactionAndClear(em);
            }
            try {
                if (env.isTransactionActive(em)) {
                    env.commitTransactionAndClear(em);
                }
            } catch (RuntimeException e) {
                if (!checkForIllegalStateException(e)) {
                    throw e;
                }
                flushFailed = true;
            }
            verify(!env.isTransactionActive(em), "Transaction still active");
            verify(flushFailed, "flush succeeded although there is a relation to a removed entity");
            em.clear();
            // case 2: implicit flush during commit
            dep = new Department(204, "dep");
            emp1 = new Employee(205, "first", "last", dep);
            proj = new Project("project");
            emp1Projects = new HashSet<Project>();
            emp1Projects.add(proj);
            emp1.setProjects(emp1Projects);
            projEmployees = new HashSet<Employee>();
            projEmployees.add(emp1);
            proj.setEmployees(projEmployees);
            env.beginTransaction(em);
            em.persist(proj);
            em.persist(dep);
            em.persist(emp1);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            dep = em.find(Department.class, new Integer(dep.getId()));
            proj = em.find(Project.class, proj.getId());
            em.remove(proj);
            emp1 = em.find(Employee.class, new Integer(emp1.getId()));
            // copy all projects from emp1 to emp2 with out actually touching them
            emp2 = new Employee(206, "aaa", "bbb", dep);
            emp2.setProjects(emp1.getProjects());
            em.persist(emp2);
            flushFailed = false;
            try {
                env.commitTransactionAndClear(em);
            } catch (RuntimeException e) {
                if (!checkForIllegalStateException(e)) {
                    throw e;
                }
                flushFailed = true;
            }
            verify(!env.isTransactionActive(em), "Transaction still active");
            verify(flushFailed, "flush succeeded although there is a relation to a removed entity");
            em.clear();
        } finally {
            closeEntityManager(em);
        }
    }

    /**
     * Force an exception during flush and check whether the current transaction is rolled back.
     */
    @Test
    public void testWithException() {
        JPAEnvironment env = getEnvironment();
        EntityManager em = env.getEntityManager();
        try {
            Node node = new Node(301, true); // PostPersist method will throw a Node.MyRuntimeException
            env.beginTransaction(em);
            em.persist(node);
            boolean flushFailed = false;
            try {
                em.flush();
            } catch (Node.MyRuntimeException e) {
                // $JL-EXC$ this is expected behavior
                flushFailed = true;
                verify(env.isTransactionMarkedForRollback(em),
                        "IllegalStateException during flush did not mark transaction for rollback");
            }
            verify(flushFailed, "callback method did not throw exception as expected");
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testRestoreFieldAfterFlush() {
        JPAEnvironment env = getEnvironment();
        EntityManager em = env.getEntityManager();
        try {
            final String initial = "initial";
            final int id = 301;
            Department department = new Department(id, initial);
            env.beginTransaction(em);
            em.persist(department);
            department.setName("changed");
            em.flush();
            // undo the change between flush and commit (on a new entity)
            department.setName(initial);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            department = em.find(Department.class, Integer.valueOf(id));
            verify(initial.equals(department.getName()), "wrong name: " + department.getName());
            department.setName("changed");
            em.flush();
            // lets try the same with a managed field
            department.setName(initial);
            env.commitTransactionAndClear(em);
            department = em.find(Department.class, Integer.valueOf(id));
            verify(initial.equals(department.getName()), "wrong name: " + department.getName());
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testRestoreRelationAfterFlush() {
        JPAEnvironment env = getEnvironment();
        EntityManager em = env.getEntityManager();
        try {
            final int id = 302;
            Employee frank = new Employee(id, "Frank", "Schuster", null);
            env.beginTransaction(em);
            Review r1 = new Review(101, Date.valueOf("2006-10-19"), "Performance");
            frank.addReview(r1);
            Review r2 = new Review(102, Date.valueOf("2006-10-19"), "Passion");
            frank.addReview(r2);
            Review r3 = new Review(103, Date.valueOf("2006-10-19"), "Six-Sigma");
            frank.addReview(r3);
            em.persist(frank);
            em.persist(r1);
            em.persist(r2);
            em.persist(r3);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            frank = em.find(Employee.class, Integer.valueOf(id));
            Set<Review> reviewsFound = frank.getReviews();
            int foundSize = reviewsFound.size();
            // lets remove a department the same with a managed field
            Set<Review> set = new HashSet<Review>();
            set.add(r1);
            set.add(r2);
            frank.setReviews(set);
            em.flush();
            // undo the change
            frank.setReviews(reviewsFound);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            frank = em.find(Employee.class, Integer.valueOf(id));
            verify(frank.getReviews().size() == foundSize, "wrong number of reviews: " + frank.getReviews().size());
            env.rollbackTransactionAndClear(em);
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testNoTransaction() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            em.flush();
            flop("exception not thrown as expected");
        } catch (TransactionRequiredException e) {
            // $JL-EXC$ expected behavior
        } finally {
            closeEntityManager(em);
        }
    }

    @SuppressWarnings("unchecked")
    @Test
    public void testTransactionMarkedForRollback() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        Department dep = new Department(401, "dep401");
        try {
            env.beginTransaction(em);
            em.persist(dep);
            env.markTransactionForRollback(em);
            em.flush();
            // verify that entity is inserted
            Query query = em.createQuery("select d from Department d where d.id = ?1");
            query.setParameter(1, Integer.valueOf(dep.getId()));
            List<Department> result = query.getResultList();
            verify(result.size() == 1, "query returned " + result.size() + " entities");
            env.rollbackTransaction(em);
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    @Bugzilla(bugid=309681)
    public void testChangedEntityIgnoredByFlush() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        Employee emp = new Employee(911, "Robi", "Tobi", null);
        try {
            env.beginTransaction(em);
            em.persist(emp);
            env.commitTransactionAndClear(em);

            env.beginTransaction(em);
            Employee found = em.find(Employee.class, 911);
            found.clearPostUpdate();
            found.setLastName("lesbar");
            em.createQuery("select i from Island i").getResultList();
            verify(!found.postUpdateWasCalled(), "post update was called");
            env.rollbackTransactionAndClear(em);

        } finally {
            closeEntityManager(em);
        }
    }

}
