package org.hivedb.hibernate.simplified; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.Session; import org.hibernate.shards.strategy.access.SequentialShardAccessStrategy; import org.hivedb.hibernate.simplified.session.HiveSessionFactory; import org.hivedb.hibernate.simplified.session.HiveSessionFactoryImpl; import org.hivedb.hibernate.simplified.session.SingletonHiveSessionFactoryBuilder; import org.hivedb.util.Lists; import org.hivedb.util.database.test.HiveTest; import org.hivedb.util.database.test.WeatherReport; import org.hivedb.util.database.test.WeatherReportImpl; import static org.junit.Assert.*; import org.junit.Test; import java.util.Collection; import java.util.List; @HiveTest.Config("hive_default") public class ErrorCorrectingDataAccessObjectSaveTest extends HiveTest{ private final static Log log = LogFactory.getLog(ErrorCorrectingDataAccessObjectSaveTest.class); private HiveSessionFactoryImpl hiveSessionFactory; @Test public void shouldSaveEntities() throws Exception { DataAccessObject<WeatherReport, Integer> dao = new ErrorCorrectingDataAccessObject<WeatherReport, Integer>(WeatherReport.class, getEntityHiveConfig().getEntityConfig(WeatherReport.class),getHive(), getSessionFactory()); WeatherReport original = WeatherReportImpl.generate(); dao.save(original); WeatherReport fetched = dao.get(original.getReportId()); assertEquals(original, fetched); } @Test public void shouldSaveManyEntities() throws Exception { ErrorCorrectingDataAccessObject<WeatherReport, Integer> dao = new ErrorCorrectingDataAccessObject<WeatherReport, Integer>(WeatherReport.class, getEntityHiveConfig().getEntityConfig(WeatherReport.class),getHive(), getSessionFactory()); Collection<WeatherReport> reports = Lists.newArrayList(); for(int i=0; i<100; i++) reports.add(WeatherReportImpl.generate()); dao.saveAll(reports); for(WeatherReport report : reports) assertTrue(dao.exists(report.getReportId())); } @Test public void shouldSaveAndReIndexIfAnEntityExistsOnTheDataNodeButNotTheDirectory() throws Exception { DataAccessObject<WeatherReport, Integer> dao = new ErrorCorrectingDataAccessObject<WeatherReport, Integer>(WeatherReport.class, getEntityHiveConfig().getEntityConfig(WeatherReport.class),getHive(), getSessionFactory()); WeatherReport report = getPersistentInstance(dao); hive.directory().deleteResourceId("WeatherReport", report.getReportId()); assertFalse(hive.directory().getNodeIdsOfResourceId("WeatherReport", report.getReportId()).size() > 0); report.setRegionCode(87654); dao.save(report); assertTrue(hive.directory().getNodeIdsOfResourceId("WeatherReport", report.getReportId()).size() > 0); WeatherReport thawed = dao.get(report.getReportId()); assertEquals(report, thawed); } @Test public void shouldSaveEntitiesWhenThePartitionKeyChanges() throws Exception { DataAccessObject<WeatherReport, Integer> dao = new ErrorCorrectingDataAccessObject<WeatherReport, Integer>(WeatherReport.class, getEntityHiveConfig().getEntityConfig(WeatherReport.class),getHive(), getSessionFactory()); WeatherReport report = getPersistentInstance(dao); String oldContinent = report.getContinent(); String newContinent = report.getContinent().equals("Asia") ? "Australia" : "Asia"; report.setContinent(newContinent); dao.save(report); Session oldNodeSession = null; Session newNodeSession = null; try { oldNodeSession = hiveSessionFactory.openSession(oldContinent); newNodeSession = hiveSessionFactory.openSession(newContinent); if(!hive.directory().getNodeIdsOfPrimaryIndexKey(oldContinent).equals(hive.directory().getNodeIdsOfPrimaryIndexKey(newContinent))) assertNull(oldNodeSession.get(WeatherReport.class, report.getReportId())); WeatherReport fetched = (WeatherReport) newNodeSession.get(WeatherReport.class, report.getReportId()); assertNotNull(fetched); assertEquals(newContinent, fetched.getContinent()); } finally { if(oldNodeSession != null) oldNodeSession.close(); if(newNodeSession != null) newNodeSession.close(); } } @Test public void shouldDeleteRecords() throws Exception { DataAccessObject<WeatherReport, Integer> dao = new ErrorCorrectingDataAccessObject<WeatherReport, Integer>(WeatherReport.class, getEntityHiveConfig().getEntityConfig(WeatherReport.class),getHive(), getSessionFactory()); WeatherReport report = getPersistentInstance(dao); assertTrue(dao.exists(report.getReportId())); dao.delete(report.getReportId()); assertFalse(dao.exists(report.getReportId())); } @Test public void shouldNotThrowAnExceptionWhenDeletingNonExistentRecords() throws Exception { DataAccessObject<WeatherReport, Integer> dao = new ErrorCorrectingDataAccessObject<WeatherReport, Integer>(WeatherReport.class, getEntityHiveConfig().getEntityConfig(WeatherReport.class),getHive(), getSessionFactory()); WeatherReport report = WeatherReportImpl.generate(); assertFalse(dao.exists(report.getReportId())); dao.delete(report.getReportId()); assertFalse(dao.exists(report.getReportId())); } private HiveSessionFactory getSessionFactory() { if(hiveSessionFactory==null) hiveSessionFactory = (HiveSessionFactoryImpl) new SingletonHiveSessionFactoryBuilder(getHive(), (List<Class<?>>) getMappedClasses(),new SequentialShardAccessStrategy()).getSessionFactory(); return hiveSessionFactory; } private WeatherReport getPersistentInstance(DataAccessObject<WeatherReport, Integer> dao) { return dao.save(WeatherReportImpl.generate()); } }