/* * Hibernate OGM, Domain model persistence for NoSQL datastores * * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.ogm.datastore.mongodb.test.associations; import static org.hibernate.ogm.datastore.mongodb.utils.MongoDBTestHelper.assertDocument; import java.lang.annotation.ElementType; import java.util.HashMap; import java.util.Map; import org.hibernate.Transaction; import org.hibernate.ogm.OgmSession; import org.hibernate.ogm.OgmSessionFactory; import org.hibernate.ogm.backendtck.associations.collection.types.Address; import org.hibernate.ogm.backendtck.associations.collection.types.Department; import org.hibernate.ogm.backendtck.associations.collection.types.Enterprise; import org.hibernate.ogm.backendtck.associations.collection.types.PhoneNumber; import org.hibernate.ogm.backendtck.associations.collection.types.PhoneNumber.PhoneNumberId; import org.hibernate.ogm.backendtck.associations.collection.types.User; import org.hibernate.ogm.datastore.document.options.MapStorageType; import org.hibernate.ogm.datastore.mongodb.MongoDB; import org.hibernate.ogm.utils.OgmTestCase; import org.hibernate.ogm.utils.TestHelper; import org.junit.Test; /** * @author Gunnar Morling */ public class MapMappingTest extends OgmTestCase { @Test public void testMapOfEntity() throws Exception { OgmSession session = openSession(); Transaction tx = session.beginTransaction(); Address home = new Address(); home.setCity( "Paris" ); Address work = new Address(); work.setCity( "San Francisco" ); User user = new User(); user.getAddresses().put( "home", home ); user.getAddresses().put( "work", work ); session.persist( home ); session.persist( work ); session.persist( user ); tx.commit(); session.clear(); tx = session.beginTransaction(); // Then assertDocument( session.getSessionFactory(), // collection "User", // query "{ '_id' : '" + user.getId() + "' }", // expected "{ " + "'_id' : '" + user.getId() + "', " + "'addresses' : {" + "'home' : '" + home.getId() + "'," + "'work' : '" + work.getId() + "'" + "}" + "}" ); // clean-up user = session.get( User.class, user.getId() ); session.delete( user ); session.delete( session.load( Address.class, home.getId() ) ); session.delete( session.load( Address.class, work.getId() ) ); tx.commit(); session.close(); checkCleanCache(); } @Test public void testMapOfEntityUsingListStrategy() throws Exception { OgmSession session = openSession(); Transaction tx = session.beginTransaction(); PhoneNumber home = new PhoneNumber( new PhoneNumberId( "DE", 123 ), "Home Phone" ); PhoneNumber work = new PhoneNumber( new PhoneNumberId( "EN", 456 ), "Work Phone" ); User user = new User(); user.getAlternativePhoneNumbers().put( "home", home ); user.getAlternativePhoneNumbers().put( "work", work ); session.persist( home ); session.persist( work ); session.persist( user ); tx.commit(); session.clear(); tx = session.beginTransaction(); // Then assertDocument( session.getSessionFactory(), // collection "User", // query "{ '_id' : '" + user.getId() + "' }", // expected "{ " + "'_id' : '" + user.getId() + "', " + "'alternativePhoneNumbers' : [" + "{ 'phoneType' : 'home', 'countryCode' : 'DE', 'number' : 123 }," + "{ 'phoneType' : 'work', 'countryCode' : 'EN', 'number' : 456 }" + "]" + "}" ); // clean-up user = session.get( User.class, user.getId() ); session.delete( user ); session.delete( session.load( PhoneNumber.class, home.getId() ) ); session.delete( session.load( PhoneNumber.class, work.getId() ) ); tx.commit(); session.close(); checkCleanCache(); } @Test public void testMapOfEntityUsingListStrategyConfiguredViaOptionApi() throws Exception { Map<String, Object> settings = new HashMap<String, Object>(); TestHelper.configureOptionsFor( settings, MongoDB.class ) .entity( User.class ) .property( "addresses", ElementType.METHOD ) .mapStorage( MapStorageType.AS_LIST ); OgmSessionFactory sessionFactory = TestHelper.getDefaultTestSessionFactory( settings, getAnnotatedClasses() ); OgmSession session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Address home = new Address(); home.setCity( "Paris" ); Address work = new Address(); work.setCity( "San Francisco" ); User user = new User(); user.getAddresses().put( "home", home ); user.getAddresses().put( "work", work ); session.persist( home ); session.persist( work ); session.persist( user ); tx.commit(); session.clear(); tx = session.beginTransaction(); assertDocument( session.getSessionFactory(), // collection "User", // query "{ '_id' : '" + user.getId() + "' }", // expected "{ " + "'_id' : '" + user.getId() + "', " + "'addresses' : [" + "{ 'addressType' : 'home', 'addresses_id' : '" + home.getId() + "' }," + "{ 'addressType' : 'work', 'addresses_id' : '" + work.getId() + "' }" + "]" + "}" ); // clean-up user = session.get( User.class, user.getId() ); session.delete( user ); session.delete( session.load( Address.class, home.getId() ) ); session.delete( session.load( Address.class, work.getId() ) ); tx.commit(); session.close(); sessionFactory.close(); checkCleanCache(); } @Test public void testMapOfEntityWithCompositeId() throws Exception { OgmSession session = openSession(); Transaction tx = session.beginTransaction(); PhoneNumber home = new PhoneNumber( new PhoneNumberId( "DE", 123 ), "Home Phone" ); PhoneNumber work = new PhoneNumber( new PhoneNumberId( "EN", 456 ), "Work Phone" ); User user = new User(); user.getPhoneNumbers().put( "home", home ); user.getPhoneNumbers().put( "work", work ); session.persist( home ); session.persist( work ); session.persist( user ); tx.commit(); session.clear(); tx = session.beginTransaction(); // Then assertDocument( session.getSessionFactory(), // collection "User", // query "{ '_id' : '" + user.getId() + "' }", // expected "{ " + "'_id' : '" + user.getId() + "', " + "'phoneNumbers' : {" + "'home' : { 'countryCode' : 'DE', 'number' : 123 }," + "'work' : { 'countryCode' : 'EN', 'number' : 456 }" + "}" + "}" ); // clean-up user = session.get( User.class, user.getId() ); session.delete( user ); session.delete( session.load( PhoneNumber.class, home.getId() ) ); session.delete( session.load( PhoneNumber.class, work.getId() ) ); tx.commit(); session.close(); checkCleanCache(); } @Test public void testMapWithNonStringKey() throws Exception { OgmSession session = openSession(); Transaction tx = session.beginTransaction(); PhoneNumber home = new PhoneNumber( new PhoneNumberId( "DE", 123 ), "Home Phone" ); PhoneNumber work = new PhoneNumber( new PhoneNumberId( "EN", 456 ), "Work Phone" ); User user = new User(); user.getPhoneNumbersByPriority().put( 1, home ); user.getPhoneNumbersByPriority().put( 2, work ); session.persist( home ); session.persist( work ); session.persist( user ); tx.commit(); session.clear(); tx = session.beginTransaction(); // Then assertDocument( session.getSessionFactory(), // collection "User", // query "{ '_id' : '" + user.getId() + "' }", // expected "{ " + "'_id' : '" + user.getId() + "', " + "'phoneNumbersByPriority' : [" + "{ 'priority' : 1, 'countryCode' : 'DE', 'number' : 123 }," + "{ 'priority' : 2, 'countryCode' : 'EN', 'number' : 456 }" + "]" + "}" ); // clean-up user = session.get( User.class, user.getId() ); session.delete( user ); session.delete( session.load( PhoneNumber.class, home.getId() ) ); session.delete( session.load( PhoneNumber.class, work.getId() ) ); tx.commit(); session.close(); checkCleanCache(); } @Test public void testMapOfComponent() { OgmSession session = openSession(); Transaction tx = session.beginTransaction(); Map<String, Department> departments = new HashMap<>(); departments.put( "sawing", new Department( "Sawing", 7 ) ); departments.put( "sale", new Department( "Sale", 2 ) ); Enterprise timberTradingInc = new Enterprise( "enterprise-1", departments ); session.persist( timberTradingInc ); tx.commit(); session.clear(); tx = session.beginTransaction(); // assert assertDocument( session.getSessionFactory(), // collection "Enterprise", // query "{ '_id' : 'enterprise-1' }", // expected "{ " + "'_id' : 'enterprise-1', " + "'departments' : {" + "'sawing' : { 'name' : 'Sawing', 'headCount' : 7 }," + "'sale' : { 'name' : 'Sale', 'headCount' : 2 }," + "}" + "}" ); // clean up session.delete( timberTradingInc ); tx.commit(); session.close(); checkCleanCache(); } @Test public void testMapWithSimpleValueType() { OgmSession session = openSession(); Transaction tx = session.beginTransaction(); Enterprise timberTradingInc = new Enterprise( "enterprise-1", null ); timberTradingInc.getRevenueByDepartment().put( "sale", 1000 ); timberTradingInc.getRevenueByDepartment().put( "sawing", 2000 ); timberTradingInc.getRevenueByDepartment().put( "planting", 3000 ); session.persist( timberTradingInc ); tx.commit(); session.clear(); tx = session.beginTransaction(); // assert assertDocument( session.getSessionFactory(), // collection "Enterprise", // query "{ '_id' : 'enterprise-1' }", // expected "{ " + "'_id' : 'enterprise-1', " + "'revenueByDepartment' : {" + "'sawing' : 2000," + "'sale' : 1000," + "'planting' : 3000," + "}" + "}" ); // clean up session.delete( timberTradingInc ); tx.commit(); session.close(); checkCleanCache(); } @Override protected Class<?>[] getAnnotatedClasses() { return new Class<?>[] { User.class, Address.class, PhoneNumber.class, Enterprise.class }; } }