blob: 872627dd90d23e039d309907c1cf15acce4115fd [file] [log] [blame]
/*
* 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.DataRecord;
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 DataRecord))
|| !(((DataRecord)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();
}
}
}