/*
 * 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.persistence.access;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import javax.persistence.Query;

import org.apache.openjpa.meta.AccessCode;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.MetaDataRepository;
import org.apache.openjpa.persistence.ArgumentException;
import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
import org.apache.openjpa.persistence.test.SingleEMFTestCase;

// -ea -Dopenjpa.ConnectionDriverName=com.mysql.jdbc.Driver -Dopenjpa.ConnectionPassword=openjpatst
// -Dopenjpa.ConnectionURL=jdbc:mysql://localhost:3306/openjpatst -Dopenjpa.ConnectionUserName=openjpatst
public class TestExplicitAccess extends SingleEMFTestCase {

    @Override
    public void setUp() {
        setUp(CLEAR_TABLES,
            "openjpa.jdbc.DBDictionary", "(defaultFractionLength=6)",
            PropAccess.class, FieldAccess.class,
            DefFieldMixedPropAccess.class , DefPropMixedFieldAccess.class,
            AbstractMappedSuperField.class, PropertySub.class,
            MappedSuperField.class, PropertySub2.class,
            SuperFieldEntity.class, PropertySub3.class,
            AbstractMappedSuperProperty.class, FieldSub.class,
            MappedSuperProperty.class, FieldSub2.class,
            SuperPropertyEntity.class, FieldSub3.class,
            MixedMappedSuper.class, MixedFieldSub.class,
            FieldEmbedEntity.class, EmbedFieldAccess.class,
            PropEmbedEntity.class, EmbedPropAccess.class,
            PropMixedEntity.class, EmbedMixedAccess.class,
            MixedNestedEmbedEntity.class, EmbedInnerProp.class,
            EmbedOuterField.class, MixedMultEmbedEntity.class,
            FieldAccessPropStratsEntity.class,
            PropAccessFieldStratsEntity.class,
            EmbedId.class, MenuItem.class, Ingredient.class, Quantity.class);
    }


    /**
     * Validates the use of field level access on an
     * entity, mappedsuperclass, and embeddable at the
     * class level.
     */
    public void testClassSpecifiedFieldAccess() {

        OpenJPAEntityManagerSPI em = emf.createEntityManager();

        FieldAccess fa = new FieldAccess();
        // Set the persistent field through a misnamed setter
        fa.setStringField("FieldAccess");

        em.getTransaction().begin();
        em.persist(fa);
        em.getTransaction().commit();
        em.clear();

        // This value of a persistent field was set using the setter
        // above, but this query will use the field name to verify that
        // field access is in use.
        Query qry = em.createNamedQuery("FieldAccess.query");
        qry.setParameter("id", fa.getId());
        qry.setParameter("strVal", "FieldAccess");
        FieldAccess fa2 = (FieldAccess)qry.getSingleResult();
        assertEquals(fa.getId(), fa2.getId());

        em.close();
    }

    /**
     * Validates the use of property level access on an
     * entity, mappedsuperclass, and embeddable at the
     * class level.
     */
    public void testClassSpecifiedPropertyAccess() {

        OpenJPAEntityManagerSPI em = emf.createEntityManager();

        PropAccess pa = new PropAccess();
        // Set the persistent field through a misnamed setter
        pa.setStrProp("PropertyAccess");

        em.getTransaction().begin();
        em.persist(pa);
        em.getTransaction().commit();
        em.clear();

        // This value of a persistent field was set using the setter
        // above, but this query will use the field name to verify that
        // field access is in use.
        Query qry = em.createNamedQuery("PropertyAccess.query");
        qry.setParameter("id", pa.getId());
        qry.setParameter("strVal", "PropertyAccess");
        PropAccess pa2 = (PropAccess)qry.getSingleResult();
        assertEquals(pa, pa2);
        em.close();
    }

    /**
     * Validates the use of explicit field access on an entity,
     * mappedsuperclass, and embeddable with property access
     * defined at the class level and field access defined
     * on specific methods.
     */
    public void testClassSpecifiedMixedSinglePCFieldAccess() {

        OpenJPAEntityManagerSPI em = emf.createEntityManager();

        DefFieldMixedPropAccess dfmpa = new DefFieldMixedPropAccess();
        // Call non-PC setter
        dfmpa.setStrField("NonPCSetter");
        // Call setter with property access
        dfmpa.setStringField("DFMPA");

        em.getTransaction().begin();
        em.persist(dfmpa);
        em.getTransaction().commit();
        em.clear();

        // This value of a persistent property was set using the setter
        // above, but this query will use the property name to verify that
        // propety access is in use.
        Query qry = em.createNamedQuery("DFMPA.query");
        qry.setParameter("id", dfmpa.getId());
        qry.setParameter("strVal", "DFMPA");
        DefFieldMixedPropAccess dfmpa2 =
            (DefFieldMixedPropAccess)qry.getSingleResult();
        assertEquals(dfmpa, dfmpa2);
        assertEquals(dfmpa2.getStringField(), "DFMPA");

        try {
            qry = em.createNamedQuery("DFMPA.badQuery");
            qry.setParameter("id", dfmpa.getId());
            qry.setParameter("strVal", "DFMPA");
            qry.getSingleResult();
            fail("Usage of this query should have thrown an exception");
        }
        catch (Exception e) {
            assertExceptionMessage(e, ArgumentException.class,
                "No field named \"strField\" in \"DefFieldMixedPropAccess\"",
                "[id, stringField, version]");
        }

        em.close();
    }

    /**
     * Validates the use of explicit property access on an entity,
     * mappedsuperclass, and embeddable with field access
     * defined at the class level and property access defined
     * on specific methods.
     */
    public void testClassSpecifiedMixedSinglePCPropertyAccess() {

        OpenJPAEntityManagerSPI em = emf.createEntityManager();

        DefPropMixedFieldAccess dpmfa = new DefPropMixedFieldAccess();
        // Call setter with underlying field access
        dpmfa.setStrProp("DPMFA");

        em.getTransaction().begin();
        em.persist(dpmfa);
        em.getTransaction().commit();
        em.clear();

        // This value of a persistent field was set using the setter
        // above, but this query will use the property name to verify that
        // propety access is in use.
        Query qry = em.createNamedQuery("DPMFA.query");
        qry.setParameter("id", dpmfa.getId());
        qry.setParameter("strVal", "DPMFA");
        DefPropMixedFieldAccess dpmfa2 =
            (DefPropMixedFieldAccess)qry.getSingleResult();
        assertEquals(dpmfa, dpmfa2);
        assertEquals(dpmfa2.getStrProp(), "DPMFA");

        try {
            qry = em.createNamedQuery("DPMFA.badQuery");
            qry.setParameter("id", dpmfa.getId());
            qry.setParameter("strVal", "DPMFA");
            qry.getSingleResult();
            fail("Usage of this query should have thrown an exception");
        }
        catch (Exception e) {
            assertExceptionMessage(e, ArgumentException.class,
                "No field named \"strProp\" in \"DefPropMixedFieldAccess\"",
                "[id, strField, version]");
        }

        em.close();
    }

    /**
     * Validates that a mapped superclass using field access and an entity
     * subclass using property access get mapped properly.
     */
    public void testAbstractMappedSuperField() {
        OpenJPAEntityManagerSPI em = emf.createEntityManager();

        PropertySub ps = new PropertySub();
        // Call super setter with underlying field access
        ps.setName("AbsMappedSuperName");
        // Call base setter with property access
        Date now = new Date();
        ps.setCreateDate(now);

        em.getTransaction().begin();
        em.persist(ps);
        em.getTransaction().commit();
        em.clear();

        // This value of a persistent field was set using the setter
        // above, but this query will use the property name to verify that
        // propety access is in use.
        Query qry = em.createNamedQuery("PropertySub.query");
        qry.setParameter("id", ps.getId());
        qry.setParameter("name", "AbsMappedSuperName");
        qry.setParameter("crtDate", now);
        PropertySub ps2 =
            (PropertySub)qry.getSingleResult();
        assertEquals(ps, ps2);
        assertEquals(ps2.getName(), "AbsMappedSuperName");
        assertEquals(ps2.getCreateDate().toString(), now.toString());

        try {
            qry = em.createNamedQuery("PropertySub.badQuery");
            qry.setParameter("id", ps.getId());
            qry.setParameter("name", "AbsMappedSuperName");
            qry.setParameter("crtDate", now);
            qry.getSingleResult();
            fail("Usage of this query should have thrown an exception");
        }
        catch (Exception e) {
            assertExceptionMessage(e, ArgumentException.class,
                "No field named \"crtDate\" in \"PropertySub\"",
                "[createDate, id, name]");
        }

        em.close();
    }

    /**
     * Validates that a mapped superclass using property access and an entity
     * subclass using field access get mapped properly.
     */
    public void testAbstractMappedSuperProperty() {
        OpenJPAEntityManagerSPI em = emf.createEntityManager();

        FieldSub fs = new FieldSub();
        // Call super setter with underlying field access
        fs.setName("AbsMappedSuperName");
        // Call base setter with property access
        Date now = new Date();
        fs.setCreateDate(now);

        em.getTransaction().begin();
        em.persist(fs);
        em.getTransaction().commit();
        em.clear();

        // This value of a persistent field was set using the setter
        // above, but this query will use the property name to verify that
        // propety access is in use.
        Query qry = em.createNamedQuery("FieldSub.query");
        qry.setParameter("id", fs.getId());
        qry.setParameter("name", "AbsMappedSuperName");
        qry.setParameter("crtDate", now);
        FieldSub fs2 =
            (FieldSub)qry.getSingleResult();
        assertEquals(fs, fs2);
        assertEquals(fs2.getName(), "AbsMappedSuperName");
        assertEquals(fs2.getCreateDate().toString(), now.toString());

        try {
            qry = em.createNamedQuery("FieldSub.badQuery");
            qry.setParameter("id", fs.getId());
            qry.setParameter("name", "AbsMappedSuperName");
            qry.setParameter("crtDate", now);
            qry.getSingleResult();
            fail("Usage of this query should have thrown an exception");
        }
        catch (Exception e) {
            assertExceptionMessage(e, ArgumentException.class,
                "No field named \"createDate\" in \"FieldSub\"",
                "[crtDate, id, name]");
        }

        em.close();
    }

    /**
     * Validates that an mapped superclass using field access and an
     * entity subclass using property access get mapped properly.
     * The subclass uses a storage field in the superclass.
     */
    public void testMappedSuperField() {
        OpenJPAEntityManagerSPI em = emf.createEntityManager();

        PropertySub2 ps = new PropertySub2();
        // Call super setter with underlying field access
        ps.setName("MappedSuperName");
        // Call base setter with property access
        Date now = new Date();
        ps.setCreateDate(now);

        em.getTransaction().begin();
        em.persist(ps);
        em.getTransaction().commit();
        em.clear();

        // This value of a persistent field was set using the setter
        // above, but this query will use the property name to verify that
        // propety access is in use.
        Query qry = em.createNamedQuery("PropertySub2.query");
        qry.setParameter("id", ps.getId());
        qry.setParameter("name", "MappedSuperName");
        qry.setParameter("crtDate", now);
        PropertySub2 ps2 =
            (PropertySub2)qry.getSingleResult();
        assertEquals(ps, ps2);
        assertEquals(ps2.getName(), "MappedSuperName");
        assertEquals(ps2.getCreateDate().toString(), now.toString());

        try {
            qry = em.createNamedQuery("PropertySub2.badQuery");
            qry.setParameter("id", ps.getId());
            qry.setParameter("name", "MappedSuperName");
            qry.setParameter("crtDate", now);
            qry.getSingleResult();
            fail("Usage of this query should have thrown an exception");
        }
        catch (Exception e) {
            assertExceptionMessage(e, ArgumentException.class,
                    "No field named \"crtDate\" in \"PropertySub2\"",
                    "[createDate, id, name]");
        }

        em.close();
    }

    /**
     * Validates that an mapped superclass using field access and an
     * entity subclass using property access get mapped properly.
     * The subclass uses a storage field in the superclass.
     */
    public void testMappedSuperProperty() {
        OpenJPAEntityManagerSPI em = emf.createEntityManager();

        FieldSub2 fs = new FieldSub2();
        // Call super setter with underlying field access
        fs.setName("MappedSuperName");
        // Call base setter with property access
        Date now = new Date();
        fs.setCreateDate(now);

        em.getTransaction().begin();
        em.persist(fs);
        em.getTransaction().commit();
        em.clear();

        // This value of a persistent field was set using the setter
        // above, but this query will use the property name to verify that
        // propety access is in use.
        Query qry = em.createNamedQuery("FieldSub2.query");
        qry.setParameter("id", fs.getId());
        qry.setParameter("name", "MappedSuperName");
        qry.setParameter("crtDate", now);
        FieldSub2 fs2 =
            (FieldSub2)qry.getSingleResult();
        assertEquals(fs, fs2);
        assertEquals(fs2.getName(), "MappedSuperName");
        assertEquals(fs2.getCreateDate().toString(), now.toString());

        try {
            qry = em.createNamedQuery("FieldSub2.badQuery");
            qry.setParameter("id", fs.getId());
            qry.setParameter("name", "MappedSuperName");
            qry.setParameter("crtDate", now);
            qry.getSingleResult();
            fail("Usage of this query should have thrown an exception");
        }
        catch (Exception e) {
            assertExceptionMessage(e, ArgumentException.class,
                    "No field named \"createDate\" in \"FieldSub2\"",
                    "[crtDate, id, name]");
        }

        em.close();
    }

    /**
     * Validates that a mix of access types can be used within multiple
     * persistent classes within an inheritance hierarchy that uses
     * MappedSuperclass.
     */
    public void testMixedMappedSuper() {
        OpenJPAEntityManagerSPI em = emf.createEntityManager();

        MixedFieldSub fs = new MixedFieldSub();
        // Call super setter with underlying field access
        fs.setName("MixedMappedSuperName");
        fs.setMyFieldProp("MyFieldName");
        // Call base setter with property access
        Date now = new Date();
        fs.setCreateDate(now);

        em.getTransaction().begin();
        em.persist(fs);
        em.getTransaction().commit();
        em.clear();

        // This value of a persistent field was set using the setter
        // above, but this query will use the property name to verify that
        // propety access is in use.
        Query qry = em.createNamedQuery("MixedFieldSub.query");
        qry.setParameter("id", fs.getId());
        qry.setParameter("name", "MixedMappedSuperName");
        qry.setParameter("crtDate", now);
        qry.setParameter("myField", "MyFieldName");
        MixedFieldSub fs2 =
            (MixedFieldSub)qry.getSingleResult();
        assertEquals(fs, fs2);
        assertEquals(fs2.getName(), "MixedMappedSuperName");
        assertEquals(fs2.getCreateDate().toString(), now.toString());

        try {
            qry = em.createNamedQuery("MixedFieldSub.badQuery");
            qry.setParameter("id", fs.getId());
            qry.setParameter("name", "MixedMappedSuperName");
            qry.setParameter("myField", "MyFieldName");
            qry.getSingleResult();
            fail("Usage of this query should have thrown an exception");
        }
        catch (Exception e) {
            assertExceptionMessage(e, ArgumentException.class,
                    "No field named \"myFieldProp\" in \"MixedFieldSub\"",
                    "[createDate, mid, myField, name]");
        }

        em.close();

    }

    /**
     * Validates that a mix of access types can be used within
     * an inheritance hierarchy which uses default Entity inheritance.
     * NOTE: be sure to test with all forms of inheritance.
     */
    public void testEntityFieldDefaultInheritance() {
        OpenJPAEntityManagerSPI em = emf.createEntityManager();

        FieldSub3 fs = new FieldSub3();
        // Call super setter with underlying field access
        fs.setName("EntitySuperName");
        // Call base setter with property access
        Date now = new Date();

        fs.setCreateDate(now);

        SuperPropertyEntity spe = new SuperPropertyEntity();
        spe.setName("SuperPropertyEntity");

        em.getTransaction().begin();
        em.persist(fs);
        em.persist(spe);
        em.getTransaction().commit();
        em.clear();

        // This value of a persistent field was set using the setter
        // above, but this query will use the property name to verify that
        // propety access is in use.
        Query qry = em.createNamedQuery("FieldSub3.query");
        qry.setParameter("id", fs.getId());
        qry.setParameter("name", "EntitySuperName");
        qry.setParameter("crtDate", now);
        FieldSub3 fs2 =
            (FieldSub3)qry.getSingleResult();
        assertEquals(fs, fs2);
        assertEquals(fs2.getName(), "EntitySuperName");
        assertEquals(fs2.getCreateDate().toString(), now.toString());

        try {
            qry = em.createNamedQuery("FieldSub3.badQuery");
            qry.setParameter("id", fs.getId());
            qry.setParameter("name", "EntitySuperName");
            qry.setParameter("crtDate", now);
            qry.getSingleResult();
            fail("Usage of this query should have thrown an exception");
        }
        catch (Exception e) {
            assertExceptionMessage(e, ArgumentException.class,
                    "No field named \"createDate\" in \"FieldSub3\"",
                    "[crtDate, id, name]");
        }

        qry = em.createNamedQuery("SuperPropertyEntity.query");
        qry.setParameter("id", spe.getId());
        qry.setParameter("name", "SuperPropertyEntity");
        SuperPropertyEntity spe2 =
            (SuperPropertyEntity)qry.getSingleResult();
        assertEquals(spe, spe2);
        assertEquals(spe2.getName(), "SuperPropertyEntity");

        try {
            // This query ensures that a subclass property didn't somehow get
            // picked up by the superclass while building field metadata using
            // explicit access.
            qry = em.createNamedQuery("SuperPropertyEntity.badQuery");
            qry.setParameter("id", spe.getId());
            qry.setParameter("name", "SuperPropertyEntity");
            qry.setParameter("crtDate", now);
            qry.getSingleResult();
            fail("Usage of this query should have thrown an exception");
        }
        catch (Exception e) {
            assertExceptionMessage(e, ArgumentException.class,
                    "No field named \"crtDate\" in \"SuperPropertyEntity\"",
                    "[id, name]");
        }

        em.close();
    }

    /**
     * Validates that a mix of access types can be used within
     * an inheritance hierarchy which uses default Entity inheritance.
     * NOTE: be sure to test with all forms of inheritance.
     */
    public void testEntityPropertyDefaultInheritance() {
        OpenJPAEntityManagerSPI em = emf.createEntityManager();

        PropertySub3 ps = new PropertySub3();
        // Call super setter with underlying field access
        ps.setName("EntitySuperName");
        // Call base setter with property access
        Date now = new Date();
        ps.setCreateDate(now);

        SuperFieldEntity sfe = new SuperFieldEntity();
        sfe.setName("SuperFieldEntity");

        em.getTransaction().begin();
        em.persist(ps);
        em.persist(sfe);
        em.getTransaction().commit();
        em.clear();

        // This value of a persistent field was set using the setter
        // above, but this query will use the property name to verify that
        // propety access is in use.
        Query qry = em.createNamedQuery("PropertySub3.query");
        qry.setParameter("id", ps.getId());
        qry.setParameter("name", "EntitySuperName");
        qry.setParameter("crtDate", now);
        PropertySub3 ps2 =
            (PropertySub3)qry.getSingleResult();
        assertEquals(ps, ps2);
        assertEquals(ps2.getName(), "EntitySuperName");
        assertEquals(ps2.getCreateDate().toString(), now.toString());

        try {
            qry = em.createNamedQuery("PropertySub3.badQuery");
            qry.setParameter("id", ps.getId());
            qry.setParameter("name", "EntitySuperName");
            qry.setParameter("crtDate", now);
            qry.getSingleResult();
            fail("Usage of this query should have thrown an exception");
        }
        catch (Exception e) {
            assertExceptionMessage(e, ArgumentException.class,
                    "No field named \"crtDate\" in \"PropertySub3\"",
                    "[createDate, id, name]");
        }

        qry = em.createNamedQuery("SuperFieldEntity.query");
        qry.setParameter("id", sfe.getId());
        qry.setParameter("name", "SuperFieldEntity");
        SuperFieldEntity sfe2 =
            (SuperFieldEntity)qry.getSingleResult();
        assertEquals(sfe2, sfe2);
        assertEquals(sfe2.getName(), "SuperFieldEntity");

        try {
            // This query ensures that a subclass property didn't somehow get
            // picked up by the superclass while building field metadata using
            // explicit access.
            qry = em.createNamedQuery("SuperFieldEntity.badQuery");
            qry.setParameter("id", sfe.getId());
            qry.setParameter("name", "SuperFieldEntity");
            qry.setParameter("crtDate", now);
            qry.getSingleResult();
            fail("Usage of this query should have thrown an exception");
        }
        catch (Exception e) {
            assertExceptionMessage(e, ArgumentException.class,
                    "No field named \"crtDate\" in \"SuperFieldEntity\"",
                    "[id, name]");
        }
        em.close();
    }

    /**
     * Validates an embeddable with field access can be used within an
     * entity with property access
     */
    public void testEmbeddablesField() {
        OpenJPAEntityManagerSPI em = emf.createEntityManager();

        EmbedFieldAccess efa = new EmbedFieldAccess();
        efa.setFirstName("J");
        efa.setLastName("Tolkien");

        PropEmbedEntity pe = new PropEmbedEntity();
        pe.setName("PropEmbedEntity");
        pe.setEmbedProp(efa);

        em.getTransaction().begin();
        em.persist(pe);
        em.getTransaction().commit();

        em.clear();

        Query qry = em.createNamedQuery("PropEmbedEntity.query");
        qry.setParameter("id", pe.getId());
        qry.setParameter("name", "PropEmbedEntity");
        qry.setParameter("firstName", "J");
        qry.setParameter("lastName", "Tolkien");
        PropEmbedEntity pe2 = (PropEmbedEntity)qry.getSingleResult();
        assertEquals(pe, pe2);
        assertEquals(efa, pe2.getEmbedProp());

        try {
            qry = em.createNamedQuery("PropEmbedEntity.badQuery");
            qry.setParameter("id", pe.getId());
            qry.setParameter("name", "PropEmbedEntity");
            qry.setParameter("firstName", "J");
            qry.setParameter("lastName", "Tolkien");
            qry.getSingleResult();
            fail("Query execution should have failed.");
        } catch (Exception e) {
            assertExceptionMessage(e, ArgumentException.class,
                    "No field named \"firstName\" in \"EmbedFieldAccess\"",
                    "[fName, lName]");
        }

        em.close();
    }

    /**
     * Validates an embeddable with property access can be used within an
     * entity with field access
     */
    public void testEmbeddablesProperty() {
        OpenJPAEntityManagerSPI em = emf.createEntityManager();

        EmbedPropAccess epa = new EmbedPropAccess();
        epa.setFirstName("Walt");
        epa.setLastName("Whitman");

        FieldEmbedEntity fe = new FieldEmbedEntity();
        fe.setName("FieldEmbedEntity");
        fe.setEPA(epa);

        em.getTransaction().begin();
        em.persist(fe);
        em.getTransaction().commit();

        em.clear();

        Query qry = em.createNamedQuery("FieldEmbedEntity.query");
        qry.setParameter("id", fe.getId());
        qry.setParameter("name", "FieldEmbedEntity");
        qry.setParameter("firstName", "Walt");
        qry.setParameter("lastName", "Whitman");
        FieldEmbedEntity fe2 = (FieldEmbedEntity)qry.getSingleResult();
        assertEquals(fe, fe2);
        assertEquals(epa, fe2.getEPA());

        try {
            qry = em.createNamedQuery("FieldEmbedEntity.badQuery");
            qry.setParameter("id", fe.getId());
            qry.setParameter("name", "FieldEmbedEntity");
            qry.setParameter("firstName", "Walt");
            qry.setParameter("lastName", "Whitman");
            qry.getSingleResult();
            fail("Query execution should have failed.");
        } catch (Exception e) {
            assertExceptionMessage(e, ArgumentException.class,
                    "No field named \"fName\" in \"EmbedPropAccess\"",
                    "[firstName, lastName]");
        }

        em.close();
    }

    /**
     * Validates an embeddable with mixed access can be used within an
     * entity with mixed access
     */
    public void testMixedEmbeddables() {
        OpenJPAEntityManagerSPI em = emf.createEntityManager();

        EmbedMixedAccess ema = new EmbedMixedAccess();
        ema.setFirstName("J");
        ema.setLastName("Tolkien");
        ema.setMiddleName("R");

        PropMixedEntity pm = new PropMixedEntity();
        pm.setName("PropMixedEntity");
        pm.setEmbedProp(ema);

        em.getTransaction().begin();
        em.persist(pm);
        em.getTransaction().commit();

        em.clear();

        Query qry = em.createNamedQuery("PropMixedEntity.query");
        qry.setParameter("id", pm.getId());
        qry.setParameter("name", "PropMixedEntity");
        qry.setParameter("firstName", "J");
        qry.setParameter("lastName", "Tolkien");
        qry.setParameter("middleName", "R");
        PropMixedEntity pm2 = (PropMixedEntity)qry.getSingleResult();
        assertEquals(pm, pm2);
        assertEquals(ema, pm2.getEmbedProp());

        try {
            qry = em.createNamedQuery("PropMixedEntity.badQuery");
            qry.setParameter("id", pm.getId());
            qry.setParameter("name", "PropMixedEntity");
            qry.setParameter("firstName", "J");
            qry.setParameter("lastName", "Tolkien");
            qry.setParameter("middleName", "R");
            qry.getSingleResult();
            fail("Query execution should have failed.");
        } catch (Exception e) {
            assertExceptionMessage(e, ArgumentException.class,
                "No field named \"middleName\" in \"EmbedMixedAccess\"",
                "[firstName, lastName, mName]");
        }

        em.close();
    }

    /**
     * Validates that a mix of access types can be used within
     * an embeddable stack.
     */
    public void testNestedEmbeddables() {
        OpenJPAEntityManagerSPI em = emf.createEntityManager();

        EmbedInnerProp eip = new EmbedInnerProp();
        eip.setInnerName("Inner");
        EmbedOuterField eof = new EmbedOuterField();
        eof.setOuterName("Outer");
        eip.setOuterField(eof);

        MixedNestedEmbedEntity pm = new MixedNestedEmbedEntity();
        pm.setName("MixedNestedEmbedEntity");
        pm.setEmbedProp(eip);

        em.getTransaction().begin();
        em.persist(pm);
        em.getTransaction().commit();

        em.clear();

        Query qry = em.createNamedQuery("MixedNestedEmbedEntity.query");
        qry.setParameter("id", pm.getId());
        qry.setParameter("name", "MixedNestedEmbedEntity");
        qry.setParameter("innerName", "Inner");
        qry.setParameter("outerName", "Outer");
        MixedNestedEmbedEntity pm2 =
            (MixedNestedEmbedEntity)qry.getSingleResult();
        assertEquals(pm, pm2);
        assertEquals(eip, pm2.getEmbedProp());

        try {
            qry = em.createNamedQuery("MixedNestedEmbedEntity.badQuery");
            qry.setParameter("id", pm.getId());
            qry.setParameter("name", "MixedNestedEmbedEntity");
            qry.setParameter("innerName", "Inner");
            qry.setParameter("outerName", "Outer");
            qry.getSingleResult();
            fail("Query execution should have failed.");
        } catch (Exception e) {
            assertExceptionMessage(e, ArgumentException.class,
                "No field named \"outerName\" in \"EmbedOuterField\"",
                "[outName]");
        }

        em.close();
    }

    /**
     * Validates that a mix of access types can be used by an
     * an entity with mulitple embeddables.
     */
    public void testMultipleEmbeddables() {
        OpenJPAEntityManagerSPI em = emf.createEntityManager();

        EmbedFieldAccess efa = new EmbedFieldAccess();
        efa.setFirstName("First");
        efa.setLastName("Last");

        EmbedPropAccess epa = new EmbedPropAccess();
        epa.setFirstName("fname");
        epa.setLastName("lname");

        MixedMultEmbedEntity pm = new MixedMultEmbedEntity();
        pm.setName("MixedMultEmbedEntity");
        pm.setEmbedProp(epa);
        pm.setEmbedField(efa);

        em.getTransaction().begin();
        em.persist(pm);
        em.getTransaction().commit();

        em.clear();

        Query qry = em.createNamedQuery("MixedMultEmbedEntity.query");
        qry.setParameter("id", pm.getId());
        qry.setParameter("name", "MixedMultEmbedEntity");
        qry.setParameter("firstName", "fname");
        qry.setParameter("lastName", "lname");
        qry.setParameter("fName", "First");
        qry.setParameter("lName", "Last");
        MixedMultEmbedEntity pm2 =
            (MixedMultEmbedEntity)qry.getSingleResult();
        assertEquals(pm, pm2);
        assertEquals(epa, pm2.getEmbedProp());
        assertEquals(efa, pm2.getEmbedField());

        try {
            qry = em.createNamedQuery("MixedMultEmbedEntity.badQuery1");
            qry.setParameter("id", pm.getId());
            qry.setParameter("name", "MixedMultEmbedEntity");
            qry.setParameter("epa", epa);
            qry.getSingleResult();
            fail("Query execution should have failed.");
        } catch (Exception e) {
            assertExceptionMessage(e, ArgumentException.class,
                "No field named \"epa\" in \"MixedMultEmbedEntity\"",
                "[embedField, embedProp, mid, name]");
        }

        try {
            qry = em.createNamedQuery("MixedMultEmbedEntity.badQuery2");
            qry.setParameter("id", pm.getId());
            qry.setParameter("name", "MixedMultEmbedEntity");
            qry.setParameter("epa", epa);
            qry.setParameter("firstName", "First");
            qry.setParameter("lastName", "Last");
            qry.getSingleResult();
            fail("Query execution should have failed.");
        } catch (Exception e) {
            // no support: conditional expressional expression over embeddable
            assertException(e, ArgumentException.class);
        }

        em.close();
    }

    /**
     * Validates explicit property access can be applied to all the access
     * strategies from within an entity with explicit field access (except for
     * the id field, which is field default)
     */
    public void testPropertyAccessStrategies() {
        OpenJPAEntityManagerSPI em = emf.createEntityManager();

        PropAccessFieldStratsEntity pa = new PropAccessFieldStratsEntity();

        // Load all persistent fields
        EmbedId eid = new EmbedId();
        eid.setId(new Random().nextInt());
        eid.setCode("IdCode");
        pa.setEmbedId(eid); // embedded id

        Collection<EmbedPropAccess> elc = new ArrayList<>();
        EmbedPropAccess epa1 = new EmbedPropAccess("Abe", "Lincoln");
        EmbedPropAccess epa2 = new EmbedPropAccess("John", "Kennedy");
        elc.add(epa1);
        elc.add(epa2);
        pa.setElementCollection(elc); // element collection of embeddables

        EmbedFieldAccess efa = new EmbedFieldAccess();
        efa.setFirstName("The");
        efa.setLastName("President");
        pa.setEmbedField(efa); // embedded

        pa.setName("PropAccessFieldStratsEntity");  // basic

        PropAccess propa = new PropAccess();
        propa.setStrProp("PropAccess");
        pa.setManyToOne(propa); // many to one

        Collection<FieldAccess> fac = new ArrayList<>();
        FieldAccess fa = new FieldAccess();
        fa.setStrField("FieldAccess");
        fac.add(fa);
        pa.setOneToMany(fac); // one to many

        PropAccess pa2 = new PropAccess();
        pa2.setStrProp("PropAccess2");
        pa.setOneToOne(pa2); // one to one

        em.getTransaction().begin();
        em.persist(pa);
        em.getTransaction().commit();

        em.clear();
        // Verify list of persistent fields
        PropAccessFieldStratsEntity newpa =
            em.find(PropAccessFieldStratsEntity.class, eid);
        assertNotNull(newpa);
        // simple key validation
        assertEquals(newpa.getEmbedId(), eid);

        // Verify the persistent member names
        MetaDataRepository mdr =
            em.getConfiguration().getMetaDataRepositoryInstance();

        ClassMetaData cmd = mdr.getMetaData(PropAccessFieldStratsEntity.class,
            null, true);
        // Assert expected persistent fields and properties were created
        assertNotNull(cmd.getField("embedId"));
        assertNotNull(cmd.getField("m2one"));
        assertNotNull(cmd.getField("one2m"));
        assertNotNull(cmd.getField("one2one"));
        assertNotNull(cmd.getField("ecoll"));
        assertNotNull(cmd.getField("embed"));
        assertNotNull(cmd.getField("ver"));
        assertNotNull(cmd.getField("m2m"));

        // Name has a matching getter/setter.  Make sure the access type
        // is field & not property
        assertNotNull(cmd.getField("name"));
        assertTrue((cmd.getField("name").getAccessType() & AccessCode.FIELD) ==
            AccessCode.FIELD);

        // Assert mappings were not created for fields or properties which
        // should not be persistent
        assertNull(cmd.getField("eid"));
        assertNull(cmd.getField("elementCollection"));
        assertNull(cmd.getField("embedField"));
        assertNull(cmd.getField("version"));
        assertNull(cmd.getField("manyToOne"));
        assertNull(cmd.getField("oneToMany"));
        assertNull(cmd.getField("oneToOne"));
        assertNull(cmd.getField("manyToMany"));

        em.close();
    }

    /**
     * Validates explicit field access can be applied to all the access
     * strategies from within an entity with explicit property access (except
     * for the id field, which is property default)
     */
    public void testFieldAccessStrategies() {
        OpenJPAEntityManagerSPI em = emf.createEntityManager();

        FieldAccessPropStratsEntity fa = new FieldAccessPropStratsEntity();

        // Load all persistent fields
        EmbedId eid = new EmbedId();
        eid.setId(new Random().nextInt());
        eid.setCode("IdCode");
        fa.setEmbedId(eid); // embedded id

        Collection<EmbedPropAccess> elc = new ArrayList<>();
        EmbedPropAccess epa1 = new EmbedPropAccess("George", "Washington");
        EmbedPropAccess epa2 = new EmbedPropAccess("James", "Carter");
        elc.add(epa1);
        elc.add(epa2);
        fa.setElementCollection(elc); // element collection of embeddables

        EmbedFieldAccess efa = new EmbedFieldAccess();
        efa.setFirstName("The");
        efa.setLastName("President");
        fa.setEmbedField(efa); // embedded

        fa.setName("FieldAccessPropStratsEntity");  // basic

        PropAccess propa = new PropAccess();
        propa.setStrProp("PropAccess");
        fa.setManyToOne(propa); // many to one

        Collection<FieldAccess> fac = new ArrayList<>();
        FieldAccess fae = new FieldAccess();
        fae.setStrField("FieldAccess");
        fac.add(fae);
        fa.setOneToMany(fac); // one to many

        PropAccess pa = new PropAccess();
        pa.setStrProp("PropAccess");
        fa.setOneToOne(pa); // one to one

        em.getTransaction().begin();
        em.persist(fa);
        em.getTransaction().commit();

        em.clear();
        // Verify list of persistent fields
        FieldAccessPropStratsEntity newpa =
            em.find(FieldAccessPropStratsEntity.class, eid);
        assertNotNull(newpa);
        // simple key validation
        assertEquals(newpa.getEmbedId(), eid);

        // Verify the persistent member names
        MetaDataRepository mdr =
            em.getConfiguration().getMetaDataRepositoryInstance();

        ClassMetaData cmd = mdr.getMetaData(FieldAccessPropStratsEntity.class,
            null, true);
        // Assert expected persistent fields and properties were created
        assertNotNull(cmd.getField("eid"));
        assertNotNull(cmd.getField("elementCollection"));
        assertNotNull(cmd.getField("embedField"));
        assertNotNull(cmd.getField("version"));
        assertNotNull(cmd.getField("manyToOne"));
        assertNotNull(cmd.getField("oneToMany"));
        assertNotNull(cmd.getField("oneToOne"));
        assertNotNull(cmd.getField("manyToMany"));

        // Name has a matching getter/setter.  Make sure the access type
        // is property & not field
        assertNotNull(cmd.getField("name"));
        assertTrue((cmd.getField("name").getAccessType() & AccessCode.PROPERTY)
            == AccessCode.PROPERTY);

        // Assert mappings were not created for fields or properties which
        // should not be persistent
        assertNull(cmd.getField("embedId"));
        assertNull(cmd.getField("m2one"));
        assertNull(cmd.getField("one2m"));
        assertNull(cmd.getField("one2one"));
        assertNull(cmd.getField("ecoll"));
        assertNull(cmd.getField("embed"));
        assertNull(cmd.getField("ver"));
        assertNull(cmd.getField("m2m"));

        em.close();
    }

    /**
     * Verifies the use of a map of embeddables containing a nested
     * mixed access embeddable.
     */
    public void testMapWithNestedEmbeddable() {
        OpenJPAEntityManagerSPI em = emf.createEntityManager();

        MenuItem mi = new MenuItem();
        mi.setName("PB & J Sandwich");

        Map<String, Ingredient> ingredients = new HashMap<>();
        mi.setIngredients(ingredients);

        Ingredient i1 = new Ingredient("Peanut Butter");
        i1.setDescription("Edible brown paste, made from peanuts");
        Quantity q1 = new Quantity(1.0, "Tbsp");
        i1.setQuantity(q1);
        ingredients.put("Peanut Butter", i1);

        Ingredient i2 = new Ingredient("Jelly");
        i2.setDescription("Sweet gel, made from fruit");
        Quantity q2 = new Quantity(1.5, "Tbsp");
        i2.setQuantity(q2);
        ingredients.put("Jelly", i2);

        Ingredient i3 = new Ingredient("Bread");
        i3.setDescription("Baked material, made from flour and water");
        Quantity q3 = new Quantity(2.0, "Slice");
        i3.setQuantity(q3);
        ingredients.put("Bread", i3);

        em.getTransaction().begin();
        em.persist(mi);
        em.getTransaction().commit();
        em.clear();

        MenuItem mi2 = em.find(MenuItem.class, mi.getId());

        assertEquals(mi2.getId(), mi.getId());
        Map<String, Ingredient> ing2 = mi2.getIngredients();
        assertTrue(ing2.containsKey("Peanut Butter"));
        Quantity q = ing2.get("Peanut Butter").getQuantity();
        assertNotNull(q);
        assertEquals(1.0, q.getAmount());
        assertEquals("Tbsp", q.getUnitOfMeasure());
        assertTrue(ing2.containsKey("Jelly"));
        q = ing2.get("Jelly").getQuantity();
        assertNotNull(q);
        assertEquals(1.5, q.getAmount());
        assertEquals("Tbsp", q.getUnitOfMeasure());
        assertTrue(ing2.containsKey("Bread"));
        q = ing2.get("Bread").getQuantity();
        assertNotNull(q);
        assertEquals(2.0, q.getAmount());
        assertEquals("Slice", q.getUnitOfMeasure());

        em.remove(mi2);

        em.close();
    }

    /*
     * Simple method to verify if an exception is of the correct type and
     * that it contains the expected message fragments.
     */
    private boolean verifyException(Exception e, Class c, String...strings) {
        if (c.isInstance(e)) {
            String exMessage = e.getMessage();
            for (String msg : strings) {
                if (!exMessage.contains(msg))
                    return false;
            }
            return true;
        }
        return false;
    }
}
