/*
 * Copyright (c) 2005, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2005, 2015 SAP. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// 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 jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import jakarta.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(3, 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=311760)
    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(103, 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, 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, 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, emp1.getId());
            emp2 = em.find(Employee.class, 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(113, 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, 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, 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, emp1.getId());
            emp2 = em.find(Employee.class, 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 -{@literal >} IllegalStateException expected because of relation emp2 -{@literal >} proj1 (removed).</li>
     * </ul>
     */
    @Test
    @Bugzilla(bugid=311760)
    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, dep.getId());
            proj = em.find(Project.class, proj.getId());
            em.remove(proj);
            emp1 = em.find(Employee.class, 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, dep.getId());
            proj = em.find(Project.class, proj.getId());
            em.remove(proj);
            emp1 = em.find(Employee.class, 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, 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, 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, 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, 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, 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);
        }
    }

}
