/** * Load an entity instance given the raw column slice. This is a stop gap * solution for instanting objects using entity manager while iterating over * rows. * * @param <T> The type of entity to load for compile time type checking * @param clazz The type of entity to load for runtime instance creation * @param id ID of the instance to load * @param colSlice Raw row slice as returned from Hector API, of the type * <code>ColumnSlice<String, byte[]></code> * @return Completely instantiated persisted object */ public <T> T find(Class<T> clazz, Object id, ColumnSlice<String, byte[]> colSlice) { if (null == clazz) { throw new IllegalArgumentException("clazz cannot be null"); } if (null == id) { throw new IllegalArgumentException("id cannot be null"); } CFMappingDef<T> cfMapDef = cacheMgr.getCfMapDef(clazz, false); if (null == cfMapDef) { throw new HectorObjectMapperException("No class annotated with @" + Entity.class.getSimpleName() + " for type, " + clazz.getName()); } T obj = objMapper.createObject(cfMapDef, id, colSlice); return obj; }
/** * Load an entity instance. If the ID does not map to a persisted entity, then * null is returned. * * @param <T> The type of entity to load for compile time type checking * @param clazz The type of entity to load for runtime instance creation * @param id ID of the instance to load * @return instance of Entity or null if can't be found */ @Override public <T> T find(Class<T> clazz, Object id) { if (null == clazz) { throw new IllegalArgumentException("clazz cannot be null"); } if (null == id) { throw new IllegalArgumentException("id cannot be null"); } CFMappingDef<T> cfMapDef = cacheMgr.getCfMapDef(clazz, false); if (null == cfMapDef) { throw new HectorObjectMapperException("No class annotated with @" + Entity.class.getSimpleName() + " for type, " + clazz.getName()); } return objMapper.getObject(keyspace, cfMapDef.getEffectiveColFamName(), id); }
private <T> void parseTableAnnotation(ClassCacheMgr cacheMgr, Table anno, CFMappingDef<T> cfMapDef) { CFMappingDef<?> tmpDef; // column family can only be mapped to one class (base class) if (null != (tmpDef = cacheMgr.getCfMapDef(anno.name(), false))) { throw new HectorObjectMapperException( "classes, " + cfMapDef.getEffectiveClass().getName() + " and " + tmpDef.getEffectiveClass().getName() + ", are both mapped to ColumnFamily, " + tmpDef.getEffectiveColFamName() + ". Can only have one Class/ColumnFamily mapping - if multiple classes can be derived from a single ColumnFamily, use @" + Inheritance.class.getSimpleName()); } cfMapDef.setColFamName(anno.name()); }
@Test(expected = HectorObjectMapperException.class) public void testGetColFamMapDefByClassAnonymousSubclassNotOK() { ClassCacheMgr cacheMgr = new ClassCacheMgr(); cacheMgr.initializeCacheForClass(MyTestBean.class); assertTrue(tmplMap.get(2L).getClass().isAnonymousClass()); cacheMgr.getCfMapDef(tmplMap.get(2L).getClass(), true); }
CFMappingDef<T> cfMapDef = (CFMappingDef<T>) cacheMgr.getCfMapDef((Class<T>) obj.getClass(), true); try {
@Test public void testGetColFamMapDefByClassAnonymousClassOK() { ClassCacheMgr cacheMgr = new ClassCacheMgr(); cacheMgr.initializeCacheForClass(tmplMap.get(1L).getClass()); assertTrue(tmplMap.get(1L).getClass().isAnonymousClass()); CFMappingDef<?> cfMapDef = cacheMgr.getCfMapDef(tmplMap.get(1L).getClass(), false); assertNotNull(cfMapDef); assertEquals(MyTestBean.class, cfMapDef.getEffectiveClass()); }
@Test(expected = HectorObjectMapperException.class) public void testGetColFamMapDefByClassSubclassNotOK() { ClassCacheMgr cacheMgr = new ClassCacheMgr(); cacheMgr.initializeCacheForClass(MyTestBean.class); NewBean obj = new NewBean(); assertFalse(obj.getClass().isAnonymousClass()); cacheMgr.getCfMapDef(obj.getClass(), true); }
private void saveObj(Keyspace keyspace, Mutator<byte[]> m, Object obj) { if (null == obj) { throw new IllegalArgumentException("object cannot be null"); } @SuppressWarnings("unchecked") CFMappingDef<Object> cfMapDef = (CFMappingDef<Object>) cacheMgr.getCfMapDef(obj.getClass(), true); byte[] colFamKey = generateColumnFamilyKeyFromPojo(obj, cfMapDef); String colFamName = cfMapDef.getEffectiveColFamName(); // if object contains collection, then must delete everything first - easier // than reading the row and selectively deleting, which is an alternative if // this is too destructive if (cfMapDef.isAnyCollections()) { m.addDeletion(colFamKey, colFamName); } // must create the "add" columns after the delete to insure proper // processing order Collection<HColumn<String, byte[]>> colColl = createColumnSet(obj); for (HColumn<String, byte[]> col : colColl) { if (null == col.getName() || col.getName().isEmpty()) { throw new HectorObjectMapperException( "Column name cannot be null or empty - trying to persist to ColumnFamily, " + colFamName); } m.addInsertion(colFamKey, colFamName, col); } }
private <T> CFMappingDef<T> initializeColumnFamilyMapDef(Class<T> realClass) { CFMappingDef<T> cfMapDef = getCfMapDef(realClass, false); if (null != cfMapDef) { return cfMapDef;
@Test public void testGetColFamMapDefByClass() { ClassCacheMgr cacheMgr = new ClassCacheMgr(); cacheMgr.initializeCacheForClass(MyTestBean.class); CFMappingDef<?> cfMapDef = cacheMgr.getCfMapDef(MyTestBean.class, false); assertNotNull(cfMapDef); assertEquals( "TestBeanColumnFamily", cfMapDef.getColFamName()); assertNotNull( "Column family not registered properly", cacheMgr.getCfMapDef("TestBeanColumnFamily", false)); assertEquals(MyTestBean.class, cfMapDef.getEffectiveClass()); assertEquals("did not find @Id properly", "baseId", cfMapDef.getKeyDef().getIdPropertyMap() .values().iterator().next() .getPropDesc().getName()); assertEquals("did not setup properties properly", ColorConverter.class, cfMapDef.getPropMapByColumnName("color").getConverter().getClass()); }
@Test public void testCustomConvertedCollectionIsOneColumn() { MyConvertedCollectionBean b1 = new MyConvertedCollectionBean(); int first = 111; int second = 0; int third = -1; b1.addToList(first).addToList(second).addToList(third); Map<String, HColumn<String, byte[]>> colMap = new HectorObjectMapper(cacheMgr).createColumnMap(b1); CFMappingDef<MyConvertedCollectionBean> cfMapping = cacheMgr.getCfMapDef( MyConvertedCollectionBean.class, false); assertEquals( "collections with custom converters should be skipped by default collection mapping", colMap.size(), cfMapping.getAllProperties().size()); }
CFMappingDef<T> cfMapDef = cacheMgr.getCfMapDef(colFamName, true);
@Test public void testInheritanceWithMultiLevels() { ClassCacheMgr cacheMgr = new ClassCacheMgr(); CFMappingDef<Desk> cfMapDef = cacheMgr.initializeCacheForClass(Desk.class); CFMappingDef<Furniture> cfBaseMapDef = cacheMgr.getCfMapDef(Furniture.class, true); assertEquals(7, cfMapDef.getAllProperties().size()); assertNotNull(cfMapDef.getCfSuperMapDef()); assertNotNull(cfMapDef.getCfBaseMapDef()); assertEquals(Desk.class.getSuperclass(), cfMapDef.getCfSuperMapDef().getEffectiveClass()); assertEquals(Desk.class.getSuperclass().getSuperclass(), cfMapDef.getCfSuperMapDef() .getCfSuperMapDef() .getEffectiveClass()); assertEquals(cfBaseMapDef.getEffectiveColFamName(), cfMapDef.getEffectiveColFamName()); assertEquals("type", cfMapDef.getDiscColumn()); assertEquals("table_desk", cfMapDef.getDiscValue()); assertEquals(DiscriminatorType.STRING, cfMapDef.getDiscType()); assertEquals("id", cfMapDef.getKeyDef().getIdPropertyMap().values().iterator().next() .getPropDesc().getName()); }
@Test public void testCreateInstanceCustomIdType() { Colors id = Colors.GREEN; long longProp1 = 1L; ColumnSliceMockImpl slice = new ColumnSliceMockImpl(); slice.add("lp1", LongSerializer.get().toBytes(longProp1)); CFMappingDef<MyCustomIdBean> cfMapDef = cacheMgr.getCfMapDef(MyCustomIdBean.class, true); MyCustomIdBean obj = new HectorObjectMapper(cacheMgr).createObject(cfMapDef, id, slice); assertEquals(id, obj.getId()); assertEquals(longProp1, obj.getLongProp1()); }
slice.add("extra", StringSerializer.get().toBytes(extraProp)); CFMappingDef<MyTestBean> cfMapDef = cacheMgr.getCfMapDef(MyTestBean.class, true); MyTestBean obj = new HectorObjectMapper(cacheMgr).createObject(cfMapDef, id, slice);