public EntityManagerImpl(Keyspace keyspace, String[] classpathPrefix, ClassCacheMgr cacheMgr, HectorObjectMapper objMapper, AnnotationScanner scanner) { this.keyspace = keyspace; if (null != cacheMgr) { this.cacheMgr = cacheMgr; } else { this.cacheMgr = new ClassCacheMgr(); } if (null != objMapper) { this.objMapper = objMapper; } else { this.objMapper = new HectorObjectMapper(this.cacheMgr); } initialize(scanner, classpathPrefix); }
/** * Create Set of HColumns for the given Object. The Object must be annotated * with {@link Column} on the desired fields. * * @param obj * @return */ private Collection<HColumn<String, byte[]>> createColumnSet(Object obj) { Map<String, HColumn<String, byte[]>> map = createColumnMap(obj); if (null != map) { return map.values(); } else { return null; } }
/** * 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; }
@SuppressWarnings({ "unchecked" }) private <T> Collection<HColumn<String, byte[]>> createColumnsFromProperty(T obj, PropertyMappingDefinition md) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException, InvocationTargetException { if (!md.isCollectionType()) { byte[] colValue = createBytesFromPropertyValue(obj, md); if (null == colValue) { return null; } return Arrays.asList(createHColumn(md.getColName(), colValue)); } else { return createColumnsFromCollectionProperty(obj, md); } }
Collection<PropertyMappingDefinition> coll = cfMapDef.getAllProperties(); for (PropertyMappingDefinition md : coll) { Collection<HColumn<String, byte[]>> colColl = createColumnsFromProperty(obj, md); if (null != colColl) { for (HColumn<String, byte[]> col : colColl) { createHColumn(discColName, convertDiscTypeToColValue(discType, cfMapDef.getDiscValue()))); addAnonymousProperties(obj, cfMapDef, colSet); return colSet; } catch (SecurityException e) {
@Test public void testNonStringAnonymousValues() { AnonymousWithLongSerializer b1 = new AnonymousWithLongSerializer(); b1.addAnonymousProp("one", 1L); b1.addAnonymousProp("two", 2L); b1.addAnonymousProp("three", 3L); Map<String, HColumn<String, byte[]>> colMap = new HectorObjectMapper(cacheMgr).createColumnMap(b1); assertEquals("should have added all props as anonymous", colMap.size(), b1.getAnonymousProps() .size()); }
@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()); }
CFMappingDef<? extends T> cfMapDefInstance = determineClassType(cfMapDef, slice); setIdIfCan(cfMapDef, obj, pkObj); if (null != md && null != md.getPropDesc()) { if (!md.isCollectionType()) { setPropertyUsingColumn(obj, col, md); } else { collMapperHelper.instantiateCollection(obj, col, md); continue; } else { addToExtraIfCan(obj, cfMapDef, col);
byte[] colFamKey = generateColumnFamilyKeyFromPkObj(cfMapDef, pkObj); T obj = createObject(cfMapDef, pkObj, result.get()); return obj;
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 byte[] generateColumnFamilyKeyFromPojo(Object obj, CFMappingDef<?> cfMapDef) { List<byte[]> segmentList = new ArrayList<byte[]>(cfMapDef.getKeyDef().getIdPropertyMap().size()); for (PropertyMappingDefinition md : cfMapDef.getKeyDef().getIdPropertyMap().values()) { Method meth = md.getPropDesc().getReadMethod(); segmentList.add(callMethodAndConvertToCassandraType(obj, meth, md.getConverter())); } return keyConcatStrategy.concat(segmentList); }
Object discValue = convertColValueToDiscType(discType, discCol.getValue()); CFMappingDef<? extends T> derivedCfMapDef = derivedClasses.get(discValue); if (null == derivedCfMapDef) {
@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()); }
MyTestBean obj = new HectorObjectMapper(cacheMgr).createObject(cfMapDef, id, slice);
@SuppressWarnings("unchecked") private byte[] generateColumnFamilyKeyFromPkObj(CFMappingDef<?> cfMapDef, Object pkObj) { List<byte[]> segmentList = new ArrayList<byte[]>(cfMapDef.getKeyDef().getIdPropertyMap().size()); if (cfMapDef.getKeyDef().isComplexKey()) { Map<String, PropertyDescriptor> propertyDescriptorMap = cfMapDef.getKeyDef().getPropertyDescriptorMap(); for (String key : cfMapDef.getKeyDef().getIdPropertyMap().keySet()) { PropertyDescriptor pd = propertyDescriptorMap.get(key); segmentList.add(callMethodAndConvertToCassandraType(pkObj, pd.getReadMethod(), new DefaultConverter())); } } else { PropertyMappingDefinition md = cfMapDef.getKeyDef().getIdPropertyMap().values().iterator() .next(); segmentList.add(md.getConverter().convertObjTypeToCassType(pkObj)); } return keyConcatStrategy.concat(segmentList); }
obj.addAnonymousProp("rice", "beans"); Map<String, HColumn<String, byte[]>> colMap = new HectorObjectMapper(cacheMgr).createColumnMap(obj);