/*
* 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.backendtck.associations.collection.types;
import static org.fest.assertions.Assertions.assertThat;
import static org.fest.assertions.MapAssert.entry;
import static org.hibernate.ogm.utils.TestHelper.getCurrentDialectType;
import static org.hibernate.ogm.utils.TestHelper.getNumberOfAssociations;
import java.util.HashMap;
import java.util.Map;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.ogm.OgmSession;
import org.hibernate.ogm.backendtck.associations.collection.types.PhoneNumber.PhoneNumberId;
import org.hibernate.ogm.datastore.document.options.AssociationStorageType;
import org.hibernate.ogm.utils.GridDialectType;
import org.hibernate.ogm.utils.OgmTestCase;
import org.hibernate.ogm.utils.SkipByGridDialect;
import org.junit.Test;
/**
* @author Emmanuel Bernard <emmanuel@hibernate.org>
*/
@SkipByGridDialect(
value = { GridDialectType.INFINISPAN_REMOTE },
comment = "hibernate core doesn't supply required primary key metadata for collections"
)
public class MapTest extends OgmTestCase {
@Test
public void testMapOfEntity() throws Exception {
Session 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();
user = (User) session.get( User.class, user.getId() );
// TODO do null value
assertThat( user.getAddresses() ).as( "Map should have 2 elements" ).hasSize( 2 );
assertThat( user.getAddresses().get( "home" ).getCity() ).as( "home address should be under home" ).isEqualTo(
home.getCity() );
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 testSetElementCollectionStorageAndRemoval() throws Exception {
Session session = openSession();
Transaction tx = session.beginTransaction();
User user = new User();
user.getNicknames().add( "idrA" );
user.getNicknames().add( "day[9]" );
session.persist( user );
User user2 = new User();
user2.getNicknames().add( "idrA" );
user2.getNicknames().add( "day[9]" );
session.persist( user2 );
tx.commit();
session.clear();
if ( getCurrentDialectType().isDocumentStore() ) {
assertThat( getNumberOfAssociations( sessionFactory, AssociationStorageType.IN_ENTITY ) )
.describedAs( "Element collections should be stored within the entity document" )
.isEqualTo( 2 );
assertThat( getNumberOfAssociations( sessionFactory, AssociationStorageType.ASSOCIATION_DOCUMENT ) )
.describedAs( "Element collections should be stored within the entity document" )
.isEqualTo( 0 );
}
tx = session.beginTransaction();
user = (User) session.get( User.class, user.getId() );
assertThat( user.getNicknames() ).containsOnly( "idrA", "day[9]" );
user.getNicknames().remove( "idrA" );
tx.commit();
session.clear();
tx = session.beginTransaction();
user = (User) session.get( User.class, user.getId() );
assertThat( user.getNicknames() ).containsOnly( "day[9]" );
session.delete( user );
user2 = (User) session.get( User.class, user2.getId() );
assertThat( user2.getNicknames() ).containsOnly( "idrA", "day[9]" );
session.delete( user2 );
tx.commit();
session.close();
checkCleanCache();
}
@Test
public void testRemovalOfMapEntry() throws Exception {
// Create user with two addresses
Session 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();
// Load user and remove one address
tx = session.beginTransaction();
user = (User) session.get( User.class, user.getId() );
user.getAddresses().remove( "work" );
tx.commit();
session.clear();
// assert
tx = session.beginTransaction();
user = (User) session.get( User.class, user.getId() );
assertThat( user.getAddresses() ).hasSize( 1 );
assertThat( user.getAddresses().containsKey( "home" ) ).isTrue();
assertThat( user.getAddresses().get( "home" ).getCity() ).isEqualTo( home.getCity() );
// clean up
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 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();
user = (User) session.get( User.class, user.getId() );
assertThat( user.getPhoneNumbers().get( "home" ) ).isNotNull();
assertThat( user.getPhoneNumbers().get( "home" ).getId() ).isEqualTo( new PhoneNumberId( "DE", 123 ) );
assertThat( user.getPhoneNumbers().get( "work" ) ).isNotNull();
assertThat( user.getPhoneNumbers().get( "work" ).getId() ).isEqualTo( new PhoneNumberId( "EN", 456 ) );
assertThat( user.getPhoneNumbers() ).hasSize( 2 );
// clean-up
user = (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();
}
public void testMapOfComponent() {
Session 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
timberTradingInc = (Enterprise) session.get( Enterprise.class, "enterprise-1" );
assertThat( timberTradingInc.getDepartments() ).hasSize( 2 );
assertThat( timberTradingInc.getDepartments() ).includes( entry( "sawing", new Department( "Sawing", 7 ) ) );
assertThat( timberTradingInc.getDepartments() ).includes( entry( "sale", new Department( "Sale", 2 ) ) );
// clean up
session.delete( timberTradingInc );
tx.commit();
session.close();
checkCleanCache();
}
@Test
public void testMapWithSimpleValueType() {
Session 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
timberTradingInc = (Enterprise) session.get( Enterprise.class, "enterprise-1" );
assertThat( timberTradingInc.getRevenueByDepartment() ).includes( entry( "sawing", 2000 ) );
assertThat( timberTradingInc.getRevenueByDepartment() ).includes( entry( "sale", 1000 ) );
assertThat( timberTradingInc.getRevenueByDepartment() ).includes( entry( "planting", 3000 ) );
assertThat( timberTradingInc.getRevenueByDepartment() ).hasSize( 3 );
// clean up
session.delete( timberTradingInc );
tx.commit();
session.close();
checkCleanCache();
}
@Test
public void testMapWithStringKeyButListStyleEnforced() 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();
user = (User) session.get( User.class, user.getId() );
assertThat( user.getAlternativePhoneNumbers().get( "home" ) ).isNotNull();
assertThat( user.getAlternativePhoneNumbers().get( "home" ).getId() ).isEqualTo( new PhoneNumberId( "DE", 123 ) );
assertThat( user.getAlternativePhoneNumbers().get( "work" ) ).isNotNull();
assertThat( user.getAlternativePhoneNumbers().get( "work" ).getId() ).isEqualTo( new PhoneNumberId( "EN", 456 ) );
assertThat( user.getAlternativePhoneNumbers() ).hasSize( 2 );
// clean-up
user = (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();
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { User.class, Address.class, PhoneNumber.class, Enterprise.class };
}
}