Return-Path: Delivered-To: apmail-openjpa-commits-archive@www.apache.org Received: (qmail 1880 invoked from network); 15 Mar 2011 16:31:19 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 15 Mar 2011 16:31:19 -0000 Received: (qmail 49098 invoked by uid 500); 15 Mar 2011 16:31:19 -0000 Delivered-To: apmail-openjpa-commits-archive@openjpa.apache.org Received: (qmail 49042 invoked by uid 500); 15 Mar 2011 16:31:19 -0000 Mailing-List: contact commits-help@openjpa.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@openjpa.apache.org Delivered-To: mailing list commits@openjpa.apache.org Received: (qmail 49035 invoked by uid 99); 15 Mar 2011 16:31:19 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 15 Mar 2011 16:31:19 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 15 Mar 2011 16:31:15 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 3C7AF238896F; Tue, 15 Mar 2011 16:30:51 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1081843 - in /openjpa/branches/2.1.x: openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/ openjpa-integration/validation/src/test/resources/org/apache/openjpa/integration/validation/ openjpa-kernel/src/m... Date: Tue, 15 Mar 2011 16:30:51 -0000 To: commits@openjpa.apache.org From: jrbauer@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110315163051.3C7AF238896F@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: jrbauer Date: Tue Mar 15 16:30:50 2011 New Revision: 1081843 URL: http://svn.apache.org/viewvc?rev=1081843&view=rev Log: OPENJPA-1787 Updated "new entity" merge path through AttachManager and BrokerImpl to refrain from firing a pre-persist event before the state of the merged entity is copied to the new entity. Test cases based upon code provided by Oliver Ringel. Added: openjpa/branches/2.1.x/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/TestMerge.java (with props) Modified: openjpa/branches/2.1.x/openjpa-integration/validation/src/test/resources/org/apache/openjpa/integration/validation/persistence.xml openjpa/branches/2.1.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AttachStrategy.java openjpa/branches/2.1.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java Added: openjpa/branches/2.1.x/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/TestMerge.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/TestMerge.java?rev=1081843&view=auto ============================================================================== --- openjpa/branches/2.1.x/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/TestMerge.java (added) +++ openjpa/branches/2.1.x/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/TestMerge.java Tue Mar 15 16:30:50 2011 @@ -0,0 +1,226 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.openjpa.integration.validation; + +import javax.persistence.EntityManager; +import javax.validation.ConstraintViolationException; + +import org.apache.openjpa.conf.OpenJPAConfiguration; +import org.apache.openjpa.lib.log.Log; +import org.apache.openjpa.persistence.OpenJPAEntityManager; +import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI; +import org.apache.openjpa.persistence.OpenJPAPersistence; +import org.apache.openjpa.persistence.test.AbstractPersistenceTestCase; + +/** + * Tests the Bean Validation support when using the em.merge() + * operation. + * + * @version $Rev$ $Date$ + */ +public class TestMerge extends AbstractPersistenceTestCase { + + private static OpenJPAEntityManagerFactorySPI emf = null; + + @Override + public void setUp() throws Exception { + super.setUp(); + emf = (OpenJPAEntityManagerFactorySPI) + OpenJPAPersistence.createEntityManagerFactory( + "ConstraintPU", + "org/apache/openjpa/integration/validation/persistence.xml"); + } + + @Override + public void tearDown() throws Exception { + closeEMF(emf); + emf = null; + super.tearDown(); + } + + /** + * Verifies constraint validation occurs on a "new" merged entity only after + * the state of the persistent entity is properly set. + */ + public void testMergeNew() { + getLog().trace("testMergeNew() started"); + + // Part 1 - Create and persist a valid entity + // create EM from default EMF + OpenJPAEntityManager em = emf.createEntityManager(); + assertNotNull(em); + try { + // verify Validation Mode + @SuppressWarnings("deprecation") + OpenJPAConfiguration conf = em.getConfiguration(); + assertNotNull(conf); + assertTrue("ValidationMode", + conf.getValidationMode().equalsIgnoreCase("AUTO")); + + Person p = createPerson(em); + em.getTransaction().begin(); + p = em.merge(p); + em.getTransaction().commit(); + getLog().trace("testMergeNew() Part 1 of 2 passed"); + } catch (Exception e) { + // unexpected + getLog().trace("testMergeNew() Part 1 of 2 failed"); + fail("Caught unexpected exception = " + e); + } finally { + closeEM(em); + } + + // Part 2 - Verify that merge throws a CVE when a constraint is not met. + em = emf.createEntityManager(); + assertNotNull(em); + try { + Person p = createPerson(em); + em.getTransaction().begin(); + p.setLastName(null); // Force a CVE + p = em.merge(p); + getLog().trace("testMergeNew() Part 2 of 2 failed"); + fail("Expected a ConstraintViolationException"); + } catch (ConstraintViolationException e) { + // expected + getLog().trace("Caught expected ConstraintViolationException = " + e); + getLog().trace("testMergeNew() Part 2 of 2 passed"); + } finally { + closeEM(em); + } + } + + /** + * Verifies constraint validation occurs on a "new" merged entity only after + * the state of the persistent entity is properly set. + */ + public void testMergeExisting() { + getLog().trace("testMergeExisting() started"); + + // Part 1 - Create and persist a valid entity + // create EM from default EMF + OpenJPAEntityManager em = emf.createEntityManager(); + assertNotNull(em); + try { + // verify Validation Mode + @SuppressWarnings("deprecation") + OpenJPAConfiguration conf = em.getConfiguration(); + assertNotNull(conf); + assertTrue("ValidationMode", + conf.getValidationMode().equalsIgnoreCase("AUTO")); + + // Create and persist a new entity + Person p = createPerson(em); + em.getTransaction().begin(); + em.persist(p); + em.getTransaction().commit(); + em.clear(); + + // find the entity + p = em.find(Person.class, p.getId()); + + // modify the entity and merge + em.getTransaction().begin(); + p.setFirstName("NewFirst"); + // merge should not throw a CVE + p = em.merge(p); + em.getTransaction().commit(); + em.clear(); + p = em.find(Person.class, p.getId()); + assertEquals("NewFirst", p.getFirstName()); + getLog().trace("testMergeExisting() Part 1 of 2 passed"); + } catch (Exception e) { + // unexpected + getLog().trace("testMergeExisting() Part 1 of 2 failed"); + fail("Caught unexpected exception = " + e); + } finally { + closeEM(em); + } + + // Part 2 - Verify that merge throws a CVE when a constraint is not met. + em = emf.createEntityManager(); + assertNotNull(em); + try { + + // Create and persist a new entity + Person p = createPerson(em); + em.getTransaction().begin(); + em.persist(p); + em.getTransaction().commit(); + em.clear(); + + // find the entity + p = em.find(Person.class, p.getId()); + // detach the entity + em.detach(p); + assertFalse(em.contains(p)); + + // Set name to an invalid value (contains a space) to force a CVE upon merge+update + p.setFirstName("First Name"); + em.getTransaction().begin(); + try { + p = em.merge(p); + } catch (Throwable t) { + fail("Did not expect a CVE upon merge."); + } + // Commit should throw a CVE + em.getTransaction().commit(); + getLog().trace("testMergeExisting() Part 2 of 2 failed"); + fail("Expected a ConstraintViolationException"); + } catch (ConstraintViolationException e) { + // expected + getLog().trace("Caught expected ConstraintViolationException = " + e); + getLog().trace("testMergeExisting() Part 2 of 2 passed"); + } finally { + closeEM(em); + } + } + + + private Person createPerson(EntityManager em) { + Person p = new Person(); + p.setFirstName("First"); + p.setLastName("Last"); + p.setHomeAddress(createAddress(em)); + return p; + } + + private IAddress createAddress(EntityManager em) { + Address addr = new Address(); + addr.setCity("City"); + addr.setPhoneNumber("555-555-5555"); + addr.setPostalCode("55555"); + addr.setState("ST"); + addr.setStreetAddress("Some Street"); + if (!em.getTransaction().isActive()) { + em.getTransaction().begin(); + } + em.persist(addr); + em.getTransaction().commit(); + return addr; + } + + /** + * Internal convenience method for getting the OpenJPA logger + * + * @return + */ + private Log getLog() { + return emf.getConfiguration().getLog("Tests"); + } +} Propchange: openjpa/branches/2.1.x/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/TestMerge.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: openjpa/branches/2.1.x/openjpa-integration/validation/src/test/resources/org/apache/openjpa/integration/validation/persistence.xml URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-integration/validation/src/test/resources/org/apache/openjpa/integration/validation/persistence.xml?rev=1081843&r1=1081842&r2=1081843&view=diff ============================================================================== --- openjpa/branches/2.1.x/openjpa-integration/validation/src/test/resources/org/apache/openjpa/integration/validation/persistence.xml (original) +++ openjpa/branches/2.1.x/openjpa-integration/validation/src/test/resources/org/apache/openjpa/integration/validation/persistence.xml Tue Mar 15 16:30:50 2011 @@ -153,7 +153,8 @@ org.apache.openjpa.integration.validation.ConstraintPattern org.apache.openjpa.integration.validation.Person org.apache.openjpa.integration.validation.Address - org.apache.openjpa.integration.validation.Book + org.apache.openjpa.integration.validation.Book + org.apache.openjpa.integration.validation.Publisher AUTO