| /* |
| * Copyright (c) 2011, 2021 Oracle and/or its affiliates. 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: |
| // Oracle - initial API and implementation |
| package org.eclipse.persistence.testing.tests.jpa.mongo; |
| |
| import java.math.BigDecimal; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import jakarta.persistence.EntityManager; |
| import jakarta.persistence.EntityManagerFactory; |
| import jakarta.persistence.OptimisticLockException; |
| import jakarta.persistence.Persistence; |
| import jakarta.persistence.Query; |
| |
| import junit.framework.Test; |
| import junit.framework.TestSuite; |
| |
| import org.eclipse.persistence.config.PersistenceUnitProperties; |
| import org.eclipse.persistence.dynamic.DynamicClassLoader; |
| import org.eclipse.persistence.dynamic.DynamicEntity; |
| import org.eclipse.persistence.eis.interactions.MappedInteraction; |
| import org.eclipse.persistence.eis.interactions.QueryStringInteraction; |
| import org.eclipse.persistence.internal.nosql.adapters.mongo.MongoDatabaseConnection; |
| import org.eclipse.persistence.internal.nosql.adapters.mongo.MongoDatabaseConnectionFactory; |
| import org.eclipse.persistence.internal.nosql.adapters.mongo.MongoOperation; |
| import org.eclipse.persistence.jpa.JpaEntityManager; |
| import org.eclipse.persistence.jpa.dynamic.JPADynamicHelper; |
| import org.eclipse.persistence.nosql.adapters.mongo.Mongo3ConnectionSpec; |
| import org.eclipse.persistence.nosql.adapters.mongo.MongoPlatform; |
| import org.eclipse.persistence.sessions.Record; |
| import org.eclipse.persistence.testing.framework.junit.JUnitTestCase; |
| import org.eclipse.persistence.testing.framework.junit.JUnitTestCaseHelper; |
| import org.eclipse.persistence.testing.models.jpa.mongo.Address; |
| import org.eclipse.persistence.testing.models.jpa.mongo.Address.AddressType; |
| import org.eclipse.persistence.testing.models.jpa.mongo.Buyer; |
| import org.eclipse.persistence.testing.models.jpa.mongo.Customer; |
| import org.eclipse.persistence.testing.models.jpa.mongo.LineItem; |
| import org.eclipse.persistence.testing.models.jpa.mongo.Order; |
| |
| import com.mongodb.MongoClient; |
| import com.mongodb.MongoClientURI; |
| import com.mongodb.client.MongoDatabase; |
| |
| /** |
| * TestSuite to test MongoDB database. |
| * To run this test suite the MongoDB must be running. |
| */ |
| public class MongoDatabaseTestSuite extends JUnitTestCase { |
| |
| /** The persistence unit name. */ |
| private static final String PU_NAME = "mongo"; |
| /** The persistence unit property key for the MongoDB connection host name or IP. */ |
| private static final String PROPERTY_HOST_KEY = PersistenceUnitProperties.NOSQL_PROPERTY + "mongo.host"; |
| /** The persistence unit property key for the MongoDB connection port. */ |
| private static final String PROPERTY_PORT_KEY = PersistenceUnitProperties.NOSQL_PROPERTY + "mongo.port"; |
| /** The persistence unit property key for the MongoDB database name. */ |
| private static final String PROPERTY_DB_KEY = PersistenceUnitProperties.NOSQL_PROPERTY + "mongo.db"; |
| /** The database (MongoDB) connection URL. */ |
| private static final String DB_URL_KEY = JUnitTestCaseHelper.insertIndex(JUnitTestCaseHelper.DB_URL_KEY, null); |
| /** The database (MongoDB) connection user name test configuration property key. */ |
| private static final String DB_USER_KEY = JUnitTestCaseHelper.insertIndex(JUnitTestCaseHelper.DB_USER_KEY, null); |
| /** The database (MongoDB) connection user password test configuration property key. */ |
| private static final String DB_PWD_KEY = JUnitTestCaseHelper.insertIndex(JUnitTestCaseHelper.DB_PWD_KEY, null); |
| /** The database (MongoDB) platform class test configuration property key. */ |
| private static final String DB_PLATFORM_KEY |
| = JUnitTestCaseHelper.insertIndex(JUnitTestCaseHelper.DB_PLATFORM_KEY, null); |
| /** The test configuration property key of the EISConnectionSpec class name used to connect to the MongoDB |
| * data source. */ |
| private static final String DB_SPEC_KEY = JUnitTestCaseHelper.insertIndex(JUnitTestCaseHelper.DB_SPEC_KEY, null); |
| private static final String SERVER_SELECTION_TIMEOUT_PROPERTY = PersistenceUnitProperties.NOSQL_PROPERTY |
| + Mongo3ConnectionSpec.SERVER_SELECTION_TIMEOUT; |
| private static final String SERVER_SELECTION_TIMEOUT = "100"; |
| |
| public static Order existingOrder; |
| |
| /** The MongoDB persistence unit properties {@link Map} from the test properties {@code db.<name>}. */ |
| private final Map<String, String> properties; |
| |
| /** |
| * Create an instance of MongoDB database test suite. |
| */ |
| public MongoDatabaseTestSuite() { |
| properties = initProperties(); |
| } |
| |
| /** |
| * Create an instance of MongoDB database test suite. |
| * @param name Test suite name. |
| */ |
| public MongoDatabaseTestSuite(String name){ |
| super(name); |
| properties = initProperties(); |
| } |
| |
| boolean isEnabled() { |
| EntityManager em = createEntityManager(); |
| try { |
| beginTransaction(em); |
| MongoDatabaseConnection con = ((MongoDatabaseConnection)em.unwrap(jakarta.resource.cci.Connection.class)); |
| String version = con.getMetaData().getEISProductVersion(); |
| return version.compareTo("2.6") > 0; |
| } catch (Throwable e) { |
| throw new RuntimeException(e); |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| } |
| |
| /** |
| * Build MongoDB database test suite. Creates an instance of the {@link TestSuite} class and adds all the tests |
| * into it. |
| * @return MongoDB database test suite with all the tests. |
| */ |
| public static Test suite() { |
| TestSuite suite = new TestSuite(); |
| suite.setName("MongoDatabaseTestSuite"); |
| MongoDatabaseTestSuite testSetup = new MongoDatabaseTestSuite("testSetup"); |
| if (testSetup.isEnabled()) { |
| suite.addTest(testSetup); |
| suite.addTest(new MongoDatabaseTestSuite("testInsert")); |
| suite.addTest(new MongoDatabaseTestSuite("testFind")); |
| suite.addTest(new MongoDatabaseTestSuite("testUpdate")); |
| suite.addTest(new MongoDatabaseTestSuite("testUpdateAdd")); |
| suite.addTest(new MongoDatabaseTestSuite("testMerge")); |
| suite.addTest(new MongoDatabaseTestSuite("testLockError")); |
| suite.addTest(new MongoDatabaseTestSuite("testRefresh")); |
| suite.addTest(new MongoDatabaseTestSuite("testDelete")); |
| suite.addTest(new MongoDatabaseTestSuite("testSimpleJPQL")); |
| suite.addTest(new MongoDatabaseTestSuite("testJPQLLike")); |
| suite.addTest(new MongoDatabaseTestSuite("testComplexJPQL")); |
| suite.addTest(new MongoDatabaseTestSuite("testJPQLEnum")); |
| suite.addTest(new MongoDatabaseTestSuite("testNativeQuery")); |
| suite.addTest(new MongoDatabaseTestSuite("testExternalFactory")); |
| suite.addTest(new MongoDatabaseTestSuite("testUserPassword")); |
| suite.addTest(new MongoDatabaseTestSuite("testDynamicEntities")); |
| } |
| return suite; |
| } |
| |
| /** |
| * Get the name of the persistence unit used in the tests. |
| * @return The name of the persistence unit used in the tests. |
| */ |
| @Override |
| public String getPersistenceUnitName() { |
| return PU_NAME; |
| } |
| |
| /** |
| * Build MongoDB persistence unit properties {@link Map} from test properties {@code db.<name>}. |
| * @return Persistence unit properties {@link Map}. |
| */ |
| private static Map<String, String> initProperties() { |
| final Map<String, String> properties = new HashMap<>(); |
| final String dbUrl = JUnitTestCaseHelper.getProperty(DB_URL_KEY); |
| final String dbUser = JUnitTestCaseHelper.getProperty(DB_USER_KEY); |
| final String dbPwd = JUnitTestCaseHelper.getProperty(DB_PWD_KEY); |
| final String platform = JUnitTestCaseHelper.getProperty(DB_PLATFORM_KEY); |
| final String dbSpec = JUnitTestCaseHelper.getProperty(DB_SPEC_KEY); |
| final String logLevel = JUnitTestCaseHelper.getProperty(JUnitTestCaseHelper.LOGGING_LEVEL_KEY); |
| String uriUser = null; |
| char[] uriPwd = null; |
| if (dbUrl != null) { |
| final MongoClientURI uri = new MongoClientURI(dbUrl); |
| final List<String> hosts = uri.getHosts(); |
| final String name = uri.getDatabase(); |
| uriUser = uri.getUsername(); |
| uriPwd = uri.getPassword(); |
| if (hosts.size() > 0) { |
| final String hostPort = hosts.get(0); |
| final int splitPos = hostPort.indexOf(':'); |
| if (splitPos >= 0) { |
| final String host = hostPort.substring(0, splitPos); |
| final String port = hostPort.substring(splitPos); |
| properties.put(PROPERTY_HOST_KEY, host); |
| if (port != null && port.length() > 0) { |
| properties.put(PROPERTY_PORT_KEY, port); |
| } |
| } else { |
| properties.put(PROPERTY_HOST_KEY, hostPort); |
| } |
| } |
| if (name != null && name.length() > 0) { |
| properties.put(PROPERTY_DB_KEY, name); |
| } |
| } |
| // Database connection user name from db.user has higher priority than from URL. |
| if (dbUser != null) { |
| properties.put(PersistenceUnitProperties.JDBC_USER, dbUser); |
| } else if (uriUser != null && uriUser.length() > 0) { |
| properties.put(PersistenceUnitProperties.JDBC_USER, uriUser); |
| } |
| // Database connection user password from db.pwd has higher priority than from URL. |
| if (dbPwd != null) { |
| properties.put(PersistenceUnitProperties.JDBC_PASSWORD, dbPwd); |
| } else if (uriPwd != null && uriPwd.length > 0) { |
| properties.put(PersistenceUnitProperties.JDBC_PASSWORD, new String(uriPwd)); |
| } |
| if (platform != null) { |
| properties.put(PersistenceUnitProperties.TARGET_DATABASE, platform); |
| } |
| if (dbSpec != null) { |
| properties.put(PersistenceUnitProperties.NOSQL_CONNECTION_SPEC, dbSpec); |
| } |
| if (logLevel != null) { |
| properties.put(PersistenceUnitProperties.LOGGING_LEVEL, logLevel); |
| } |
| return properties; |
| } |
| |
| /** |
| * Update the connection user name persistence unit property value. |
| * @param properties The properties {@link Map} to be modified. |
| * @param key The connection user name persistence unit property key ({@code PersistenceUnitProperties.JDBC_USER} |
| * or {@code PersistenceUnitProperties.NOSQL_USER)}). |
| * @param value The connection user name persistence unit property value. |
| */ |
| private static void updateUserProperty( |
| final Map<String, String> properties, final String key, final String value) { |
| if (key.equals(PersistenceUnitProperties.JDBC_USER) |
| || key.equals(PersistenceUnitProperties.NOSQL_USER)) { |
| properties.remove(PersistenceUnitProperties.JDBC_USER); |
| properties.remove(PersistenceUnitProperties.NOSQL_USER); |
| properties.put(key, value); |
| } else { |
| throw new IllegalArgumentException("Invalid user persistence property key"); |
| } |
| } |
| |
| /** |
| * Update the connection user password persistence unit property value. |
| * @param properties The properties {@link Map} to be modified. |
| * @param key The connection user name persistence unit property key ({@code PersistenceUnitProperties.JDBC_PASSWORD} |
| * or {@code PersistenceUnitProperties.NOSQL_PASSWORD)}). |
| * @param value The connection user name persistence unit property value. |
| */ |
| private static void updatePasswordProperty( |
| final Map<String, String> properties, final String key, final String value) { |
| if (key.equals(PersistenceUnitProperties.JDBC_PASSWORD) |
| || key.equals(PersistenceUnitProperties.NOSQL_PASSWORD)) { |
| properties.remove(PersistenceUnitProperties.JDBC_PASSWORD); |
| properties.remove(PersistenceUnitProperties.NOSQL_PASSWORD); |
| properties.put(key, value); |
| } else { |
| throw new IllegalArgumentException("Invalid user persistence property key"); |
| } |
| } |
| |
| /** |
| * Get the MongoDB persistence unit properties {@link Map}. |
| * @return The MongoDB persistence unit properties {@link Map}. |
| */ |
| @Override |
| public Map<String, String> getPersistenceProperties() { |
| return properties; |
| } |
| |
| /** |
| * Initialize test suite. |
| */ |
| public void testSetup() { |
| EntityManager em = createEntityManager(); |
| // First clear old database. |
| beginTransaction(em); |
| MongoDatabase db = ((MongoDatabaseConnection)em.unwrap(jakarta.resource.cci.Connection.class)).getDB(); |
| db.drop(); |
| commitTransaction(em); |
| beginTransaction(em); |
| try { |
| for (int index = 0; index < 10; index++) { |
| existingOrder = new Order(); |
| existingOrder.orderedBy = "ACME"; |
| existingOrder.address = new Address(); |
| existingOrder.address.city = "Ottawa"; |
| existingOrder.address.addressee = "Bob Jones"; |
| existingOrder.address.state = "CA"; |
| existingOrder.address.country = "Mexico"; |
| existingOrder.address.zipCode = "12345"; |
| LineItem line = new LineItem(); |
| line.itemName = "stuff"; |
| line.itemPrice = new BigDecimal("10.99"); |
| line.lineNumber = 1; |
| line.quantity = 100; |
| existingOrder.lineItems.add(line); |
| line = new LineItem(); |
| line.itemName = "more stuff"; |
| line.itemPrice = new BigDecimal("20.99"); |
| line.lineNumber = 2; |
| line.quantity = 50; |
| existingOrder.lineItems.add(line); |
| existingOrder.comments.add("priority order"); |
| existingOrder.comments.add("next day"); |
| em.persist(existingOrder); |
| } |
| commitTransaction(em); |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| clearCache(); |
| } |
| |
| /** |
| * Test inserts. |
| */ |
| public void testInsert() { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| Order order = new Order(); |
| try { |
| order.orderedBy = "ACME"; |
| order.address = new Address(); |
| order.address.city = "Ottawa"; |
| order.address.type = AddressType.Work; |
| |
| LineItem item = new LineItem(); |
| item.itemName = "stuff"; |
| item.itemPrice = new BigDecimal("9.99"); |
| item.lineNumber = 1; |
| item.quantity = 50; |
| order.lineItems.add(item); |
| |
| item = new LineItem(); |
| item.itemName = "more stuff"; |
| item.itemPrice = new BigDecimal(500); |
| item.lineNumber = 2; |
| item.quantity = 1; |
| order.lineItems.add(item); |
| |
| item = new LineItem(); |
| item.itemName = "stuff"; |
| item.itemPrice = new BigDecimal("9.99"); |
| item.lineNumber = 1; |
| item.quantity = 50; |
| order.lineItemsByNumber.put(1L, item); |
| |
| item = new LineItem(); |
| item.itemName = "more stuff"; |
| item.itemPrice = new BigDecimal(500); |
| item.lineNumber = 2; |
| item.quantity = 1; |
| order.lineItemsByNumber.put(2L, item); |
| |
| em.persist(order); |
| |
| Customer customer = new Customer(); |
| customer.name = "ACME"; |
| em.persist(customer); |
| order.customer = customer; |
| order.customers.add(customer); |
| customer = new Customer(); |
| customer.name = "Startup"; |
| em.persist(customer); |
| order.customers.add(customer); |
| |
| Buyer buyer = new Buyer(); |
| buyer.id1 = 1; |
| buyer.id2 = 1; |
| buyer.name = "FOO Inc."; |
| em.persist(buyer); |
| order.buyer = buyer; |
| order.buyers.add(buyer); |
| buyer = new Buyer(); |
| buyer.id1 = 2; |
| buyer.id2 = 2; |
| buyer.name = "BAR Corp."; |
| em.persist(buyer); |
| order.buyers.add(buyer); |
| |
| commitTransaction(em); |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| verifyObjectInCacheAndDatabase(order); |
| verifyObjectInEntityManager(order); |
| } |
| |
| /** |
| * Test pass an external factory when connecting. |
| */ |
| public void testExternalFactory() throws Exception { |
| Map properties = new HashMap(); |
| MongoClient mongo = new MongoClient(); |
| MongoDatabase db = mongo.getDatabase("mydb"); |
| properties.put(PersistenceUnitProperties.NOSQL_CONNECTION_FACTORY, new MongoDatabaseConnectionFactory(db)); |
| EntityManagerFactory factory = Persistence.createEntityManagerFactory(getPersistenceUnitName(), properties); |
| EntityManager em = factory.createEntityManager(); |
| em.close(); |
| factory.close(); |
| mongo.close(); |
| } |
| |
| /** |
| * Test user/password connecting. |
| */ |
| public void testUserPassword() throws Exception { |
| Map<String, String> properties = new HashMap<String, String>(this.properties); |
| updateUserProperty(properties, PersistenceUnitProperties.JDBC_USER, "unknownuser"); |
| updatePasswordProperty(properties, PersistenceUnitProperties.JDBC_PASSWORD, "password"); |
| properties.put(SERVER_SELECTION_TIMEOUT_PROPERTY, SERVER_SELECTION_TIMEOUT); |
| boolean errorCaught = false; |
| EntityManagerFactory factory = null; |
| EntityManager em = null; |
| try { |
| factory = Persistence.createEntityManagerFactory(getPersistenceUnitName(), properties); |
| em = factory.createEntityManager(); |
| } catch (Exception expected) { |
| //Different MONGO DB drivers (versions) prints different error messages |
| if (expected.getMessage().indexOf("Authentication failed") == -1 && expected.getMessage().indexOf("auth failed") == -1 && expected.getMessage().indexOf("Exception authenticating") == -1) { |
| throw expected; |
| } |
| errorCaught = true; |
| } finally { |
| if (em != null) { |
| em.close(); |
| } |
| if (factory != null) { |
| factory.close(); |
| } |
| } |
| if (!errorCaught) { |
| fail("authentication should have failed"); |
| } |
| properties = new HashMap<String, String>(this.properties); |
| updateUserProperty(properties, PersistenceUnitProperties.NOSQL_USER, "unknownuser"); |
| updatePasswordProperty(properties, PersistenceUnitProperties.NOSQL_PASSWORD, "password"); |
| properties.put(SERVER_SELECTION_TIMEOUT_PROPERTY, SERVER_SELECTION_TIMEOUT); |
| errorCaught = false; |
| factory = null; |
| em = null; |
| try { |
| factory = Persistence.createEntityManagerFactory(getPersistenceUnitName(), properties); |
| em = factory.createEntityManager(); |
| } catch (Exception expected) { |
| //Different MONGO DB drivers (versions) prints different error messages |
| if (expected.getMessage().indexOf("Authentication failed") == -1 && expected.getMessage().indexOf("auth failed") == -1 && expected.getMessage().indexOf("Exception authenticating") == -1) { |
| throw expected; |
| } |
| errorCaught = true; |
| } finally { |
| if (em != null) { |
| em.close(); |
| } |
| if (factory != null) { |
| factory.close(); |
| } |
| } |
| if (!errorCaught) { |
| fail("authentication should have failed"); |
| } |
| } |
| |
| /** |
| * Test find. |
| */ |
| public void testFind() { |
| clearCache(); |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| Order order = null; |
| try { |
| order = em.find(Order.class, existingOrder.id); |
| compareObjects(existingOrder, order); |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| } |
| |
| /** |
| * Test updates. |
| */ |
| public void testUpdate() { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| Order order = new Order(); |
| try { |
| order.orderedBy = "ACME"; |
| order.address = new Address(); |
| order.address.city = "Ottawa"; |
| em.persist(order); |
| commitTransaction(em); |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| clearCache(); |
| em = createEntityManager(); |
| beginTransaction(em); |
| try { |
| order = em.find(Order.class, order.id); |
| order.orderedBy = "Fred Jones"; |
| order.address.addressee = "Fred Jones"; |
| commitTransaction(em); |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| verifyObjectInCacheAndDatabase(order); |
| verifyObjectInEntityManager(order); |
| } |
| |
| |
| /** |
| * Test updates. |
| */ |
| public void testUpdateAdd() { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| Order order = new Order(); |
| try { |
| order.orderedBy = "ACME"; |
| order.address = new Address(); |
| order.address.city = "Ottawa"; |
| em.persist(order); |
| commitTransaction(em); |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| clearCache(); |
| em = createEntityManager(); |
| beginTransaction(em); |
| try { |
| order = em.find(Order.class, order.id); |
| Customer customer = new Customer(); |
| em.persist(customer); |
| order.customers.add(customer); |
| order.comments.add("foo"); |
| commitTransaction(em); |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| verifyObjectInCacheAndDatabase(order); |
| verifyObjectInEntityManager(order); |
| } |
| |
| /** |
| * Test merge. |
| */ |
| public void testMerge() { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| Order order = new Order(); |
| try { |
| order.orderedBy = "ACME"; |
| order.address = new Address(); |
| order.address.city = "Ottawa"; |
| em.persist(order); |
| commitTransaction(em); |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| clearCache(); |
| em = createEntityManager(); |
| beginTransaction(em); |
| try { |
| order = em.find(Order.class, order.id); |
| order.orderedBy = "Fred Jones"; |
| order.address.addressee = "Fred Jones"; |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| em = createEntityManager(); |
| beginTransaction(em); |
| try { |
| em.merge(order); |
| commitTransaction(em); |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| clearCache(); |
| em = createEntityManager(); |
| beginTransaction(em); |
| try { |
| Order fromDatabase = em.find(Order.class, order.id); |
| order.version = order.version + 1; |
| compareObjects(order, fromDatabase); |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| } |
| |
| /** |
| * Test locking. |
| */ |
| public void testLockError() { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| Order order = new Order(); |
| try { |
| order.orderedBy = "ACME"; |
| order.address = new Address(); |
| order.address.city = "Ottawa"; |
| em.persist(order); |
| commitTransaction(em); |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| clearCache(); |
| em = createEntityManager(); |
| beginTransaction(em); |
| try { |
| Order updatedOrder = em.find(Order.class, order.id); |
| updatedOrder.orderedBy = "Fred Jones"; |
| updatedOrder.address.addressee = "Fred Jones"; |
| commitTransaction(em); |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| OptimisticLockException exception = null; |
| em = createEntityManager(); |
| beginTransaction(em); |
| try { |
| em.merge(order); |
| commitTransaction(em); |
| } catch (OptimisticLockException expected) { |
| exception = expected; |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| if (exception == null) { |
| fail("Lock error did not occur."); |
| } |
| } |
| |
| /** |
| * Test refresh. |
| */ |
| public void testRefresh() { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| Order order = new Order(); |
| try { |
| order.orderedBy = "ACME"; |
| order.address = new Address(); |
| order.address.city = "Ottawa"; |
| em.persist(order); |
| commitTransaction(em); |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| clearCache(); |
| em = createEntityManager(); |
| beginTransaction(em); |
| try { |
| order = em.find(Order.class, order.id); |
| order.orderedBy = "Fred Jones"; |
| em.refresh(order); |
| if (order.orderedBy.equals("Fred Jones")) { |
| fail("Refresh failed: " + order.orderedBy); |
| } |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| } |
| |
| /** |
| * Test JPQL. |
| */ |
| public void testSimpleJPQL() { |
| // Clear db first. |
| testSetup(); |
| EntityManager em = createEntityManager(); |
| try { |
| // all |
| Query query = em.createQuery("Select o from Order o"); |
| List results = query.getResultList(); |
| if (results.size() != 10) { |
| fail("Expected 10 results: " + results); |
| } |
| Order order = (Order)results.get(0); |
| // = |
| query = em.createQuery("Select o from Order o where o.id = :oid"); |
| query.setParameter("oid", order.id); |
| results = query.getResultList(); |
| if (results.size() != 1) { |
| fail("Expected 1 result: " + results); |
| } |
| // != |
| query = em.createQuery("Select o from Order o where o.id <> :nextId"); |
| query.setParameter("nextId", order.id); |
| results = query.getResultList(); |
| if (results.size() != 9) { |
| fail("Expected 9 result: " + results); |
| } |
| // in |
| query = em.createQuery("Select o from Order o where o.orderedBy in (:by, :by)"); |
| query.setParameter("by", "ACME"); |
| results = query.getResultList(); |
| if (results.size() != 10) { |
| fail("Expected 1 result: " + results); |
| } |
| // nin |
| query = em.createQuery("Select o from Order o where o.orderedBy not in (:by, :by)"); |
| query.setParameter("by", "ACME"); |
| results = query.getResultList(); |
| if (results.size() != 0) { |
| fail("Expected 0 result: " + results); |
| } |
| // and |
| query = em.createQuery("Select o from Order o where o.id = :nextId and o.orderedBy = 'ACME'"); |
| query.setParameter("nextId", order.id); |
| results = query.getResultList(); |
| if (results.size() != 1) { |
| fail("Expected 1 result: " + results); |
| } |
| // or |
| query = em.createQuery("Select o from Order o where o.id = :nextId or o.orderedBy = 'ACME'"); |
| query.setParameter("nextId", order.id); |
| results = query.getResultList(); |
| if (results.size() != 10) { |
| fail("Expected 10 result: " + results); |
| } |
| // not |
| query = em.createQuery("Select o from Order o where o.id = :nextId or not(o.orderedBy = 'ACME')"); |
| query.setParameter("nextId", order.id); |
| results = query.getResultList(); |
| if (results.size() != 1) { |
| fail("Expected 1 result: " + results); |
| } |
| // not + operator |
| query = em.createQuery("Select o from Order o where o.id = :nextId or not(o.id <> :nextId)"); |
| query.setParameter("nextId", order.id); |
| results = query.getResultList(); |
| if (results.size() != 1) { |
| fail("Expected 10 result: " + results); |
| } |
| // > < |
| query = em.createQuery("Select o from Order o where o.id > :nextId and o.id < :nextId"); |
| query.setParameter("nextId", order.id); |
| results = query.getResultList(); |
| if (results.size() != 0) { |
| fail("Expected 0 result: " + results); |
| } |
| // >= <= |
| query = em.createQuery("Select o from Order o where o.id >= :nextId and o.id <= :nextId"); |
| query.setParameter("nextId", order.id); |
| results = query.getResultList(); |
| if (results.size() != 1) { |
| fail("Expected 1 result: " + results); |
| } |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Test JPQL. |
| */ |
| public void testComplexJPQL() { |
| // Clear db first. |
| testSetup(); |
| EntityManager em = createEntityManager(); |
| try { |
| // embedded |
| Query query = em.createQuery("Select o from Order o where o.address.city = :city"); |
| query.setParameter("city", "Ottawa"); |
| List results = query.getResultList(); |
| if (results.size() != 10) { |
| fail("Expected 10 result: " + results); |
| } |
| query = em.createQuery("Select o from Order o join o.lineItems l where l.itemName = :name"); |
| query.setParameter("name", "stuff"); |
| results = query.getResultList(); |
| if (results.size() != 10) { |
| fail("Expected 10 result: " + results); |
| } |
| // order by |
| query = em.createQuery("Select o from Order o order by o.address.city"); |
| results = query.getResultList(); |
| if (results.size() != 10) { |
| fail("Expected 10 result: " + results); |
| } |
| query = em.createQuery("Select o from Order o order by o.orderedBy desc"); |
| results = query.getResultList(); |
| if (results.size() != 10) { |
| fail("Expected 10 result: " + results); |
| } |
| query = em.createQuery("Select o from Order o order by o.orderedBy desc, o.address.city desc"); |
| //query = em.createQuery("Select o from Order o order by o.orderedBy desc, o.address.city asc"); |
| // Can't seem to order asc and desc at same time. |
| results = query.getResultList(); |
| if (results.size() != 10) { |
| fail("Expected 10 result: " + results); |
| } |
| // select |
| query = em.createQuery("Select o.id from Order o where o.orderedBy like :orderedBy"); |
| query.setParameter("orderedBy", "ACME"); |
| results = query.getResultList(); |
| if (!(results.get(0) instanceof String)) { |
| fail("Incorrect result: " + results); |
| } |
| query = em.createQuery("Select o.id, o.address.city from Order o where o.orderedBy like :orderedBy"); |
| query.setParameter("orderedBy", "ACME"); |
| results = query.getResultList(); |
| if (!(results.get(0) instanceof Object[])) { |
| fail("Incorrect result: " + results); |
| } |
| // error |
| try { |
| query = em.createQuery("Select count(o) from Order o"); |
| query.setParameter("orderedBy", "ACME"); |
| results = query.getResultList(); |
| fail("Exception expected"); |
| } catch (Exception expected) { |
| // OK |
| } |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Test JPQL. |
| */ |
| public void testJPQLLike() { |
| // Clear db first. |
| testSetup(); |
| EntityManager em = createEntityManager(); |
| try { |
| // like |
| Query query = em.createQuery("Select o from Order o where o.orderedBy like :orderedBy"); |
| query.setParameter("orderedBy", "ACME"); |
| List results = query.getResultList(); |
| if (results.size() != 10) { |
| fail("Expected 10 result: " + results); |
| } |
| query.setParameter("orderedBy", "A%"); |
| results = query.getResultList(); |
| if (results.size() != 10) { |
| fail("Expected 10 result: " + results); |
| } |
| query.setParameter("orderedBy", "%"); |
| results = query.getResultList(); |
| if (results.size() != 10) { |
| fail("Expected 10 result: " + results); |
| } |
| query.setParameter("orderedBy", "A__E"); |
| results = query.getResultList(); |
| if (results.size() != 10) { |
| fail("Expected 10 result: " + results); |
| } |
| query.setParameter("orderedBy", "*"); |
| results = query.getResultList(); |
| if (results.size() != 0) { |
| fail("Expected 0 result: " + results); |
| } |
| query.setParameter("orderedBy", "A"); |
| results = query.getResultList(); |
| if (results.size() != 0) { |
| fail("Expected 0 result: " + results); |
| } |
| query.setParameter("orderedBy", ""); |
| results = query.getResultList(); |
| if (results.size() != 0) { |
| fail("Expected 0 result: " + results); |
| } |
| query.setParameter("orderedBy", "%E"); |
| results = query.getResultList(); |
| if (results.size() != 10) { |
| fail("Expected 10 result: " + results); |
| } |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Test enum query. |
| */ |
| public void testJPQLEnum() { |
| // Clear db first. |
| testSetup(); |
| EntityManager em = createEntityManager(); |
| try { |
| // like |
| Query query = em.createQuery("Select o from Order o where o.address.type = :type"); |
| query.setParameter("type", AddressType.Home); |
| List results = query.getResultList(); |
| if (results.size() != 0) { |
| fail("Expected 0 result: " + results); |
| } |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| /** |
| * Test native query. |
| */ |
| public void testNativeQuery() { |
| EntityManager em = createEntityManager(); |
| |
| MappedInteraction interaction = new MappedInteraction(); |
| interaction.setProperty(MongoPlatform.OPERATION, MongoOperation.FIND.name()); |
| interaction.setProperty(MongoPlatform.COLLECTION, "ORDER"); |
| interaction.setProperty(MongoPlatform.BATCH_SIZE, "10"); |
| interaction.setProperty(MongoPlatform.READ_PREFERENCE, "PRIMARY"); |
| interaction.addArgumentValue("_id", existingOrder.id); |
| Query query = em.unwrap(JpaEntityManager.class).createQuery(interaction); |
| List result = query.getResultList(); |
| if ((result.size() != 1) |
| || (!(result.get(0) instanceof Record)) |
| || !(((Record)result.get(0)).get("_id").equals(existingOrder.id))) { |
| fail("Incorrect result: " + result); |
| } |
| |
| interaction = new MappedInteraction(); |
| interaction.setProperty(MongoPlatform.OPERATION, MongoOperation.FIND.name()); |
| interaction.setProperty(MongoPlatform.COLLECTION, "ORDER"); |
| interaction.setProperty(MongoPlatform.BATCH_SIZE, "10"); |
| interaction.setProperty(MongoPlatform.READ_PREFERENCE, "PRIMARY"); |
| interaction.addArgumentValue("_id", existingOrder.id); |
| query = em.unwrap(JpaEntityManager.class).createQuery(interaction, Order.class); |
| Order order = (Order)query.getSingleResult(); |
| if ((order == null) || (!order.id.equals(existingOrder.id))) { |
| fail("Incorrect result: " + order); |
| } |
| |
| QueryStringInteraction mqlInteraction = new QueryStringInteraction(); |
| mqlInteraction.setQueryString("db.ORDER.findOne({\"_id\":\"" + existingOrder.id + "\"})"); |
| query = em.unwrap(JpaEntityManager.class).createQuery(mqlInteraction, Order.class); |
| order = (Order)query.getSingleResult(); |
| if ((order == null) || (!order.id.equals(existingOrder.id))) { |
| fail("Incorrect result: " + order); |
| } |
| |
| query = em.createNativeQuery("db.ORDER.findOne({\"_id\":\"" + existingOrder.id + "\"})", Order.class); |
| order = (Order)query.getSingleResult(); |
| if ((order == null) || (!order.id.equals(existingOrder.id))) { |
| fail("Incorrect result: " + order); |
| } |
| |
| } |
| |
| /** |
| * Test deletes. |
| */ |
| public void testDelete() { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| Order order = new Order(); |
| try { |
| order.orderedBy = "ACME"; |
| order.address = new Address(); |
| order.address.city = "Ottawa"; |
| em.persist(order); |
| commitTransaction(em); |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| clearCache(); |
| em = createEntityManager(); |
| beginTransaction(em); |
| try { |
| order = em.find(Order.class, order.id); |
| em.remove(order); |
| commitTransaction(em); |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| clearCache(); |
| em = createEntityManager(); |
| beginTransaction(em); |
| try { |
| Order fromDatabase = em.find(Order.class, order.id); |
| if (fromDatabase != null) { |
| fail("Object not deleted: " + fromDatabase); |
| } |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| } |
| |
| /** |
| * Test dynamic entities. |
| */ |
| public void testDynamicEntities() { |
| final Map<String, Object> properties = new HashMap<>(this.properties); |
| properties.put("eclipselink.classloader", new DynamicClassLoader(getClass().getClassLoader())); |
| properties.put("eclipselink.logging.level", "finest"); |
| final EntityManagerFactory factory = Persistence.createEntityManagerFactory("mongo-dynamic", properties); |
| final EntityManager em = factory.createEntityManager(); |
| beginTransaction(em); |
| try { |
| JPADynamicHelper helper = new JPADynamicHelper(em); |
| final DynamicEntity person = helper.newDynamicEntity("Person"); |
| person.set("firstname", "Boy"); |
| person.set("lastname", "Pelletier"); |
| DynamicEntity address = helper.newDynamicEntity("org.eclipse.persistence.testing.models.jpa.nosql.dynamic.Address"); |
| address.set("city", "Ottawa"); |
| List<DynamicEntity> addresses = new ArrayList<>(); |
| addresses.add(address); |
| person.set("addresses", addresses); |
| em.persist(person); |
| commitTransaction(em); |
| |
| em.createNamedQuery("Person.findAll").getResultList(); |
| |
| beginTransaction(em); |
| address = helper.newDynamicEntity("org.eclipse.persistence.testing.models.jpa.nosql.dynamic.Address"); |
| address.set("city", "Ottawa2"); |
| addresses = person.get("addresses"); |
| addresses.add(address); |
| person.set("addresses", addresses); |
| commitTransaction(em); |
| |
| factory.getCache().evictAll(); |
| em.clear(); |
| final DynamicEntity dbPerson = em.find(helper.getType("Person").getJavaClass(), person.get("id")); |
| if (((Collection)dbPerson.get("addresses")).size() != 2) { |
| fail("Expected 2 addresses: " + dbPerson.get("addresses")); |
| } |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| factory.close(); |
| } |
| } |
| |
| } |