private <T> void validatePersistableEntityClass(ClassCacheMgr cacheMgr, CFMappingDef<T> cfMapDef) { // CFMappingDef<? super T> cfSuperDef; if (null == cfMapDef.getEffectiveColFamName()) { throw new HectorObjectMapperException("Class, " + cfMapDef.getRealClass().getName() + ", is missing @" + Table.class.getSimpleName()); } // else if (null != (cfSuperDef = cacheMgr.findBaseClassViaMappings(cfMapDef))) { // throw new HectorObjectMapperException("@" + Table.class.getSimpleName() // + " can only be used once per hierarchy and has been specified in class " // + cfSuperDef.getRealClass().getName() + " and " + cfMapDef.getRealClass().getName() // + " - quitting"); // } }
private <T> void validateBaseEntityClass(ClassCacheMgr cacheMgr, CFMappingDef<T> cfMapDef) { if (null == cfMapDef.getColFamName()) { throw new HectorObjectMapperException(cfMapDef.getRealClass() + " is recognized as a base class, but doesn't specify @" + Table.class.getSimpleName() + " - quitting"); } }
private <T> void findAndSetBaseClassViaMappings(ClassCacheMgr cacheMgr, CFMappingDef<T> cfMapDef) { CFMappingDef<? super T> cfBaseMapDef = cacheMgr.findBaseClassViaMappings(cfMapDef); if (null == cfBaseMapDef) { throw new HectorObjectMapperException(cfMapDef.getRealClass() + " is a derived class entity but @" + Table.class.getSimpleName() + " is not specified in its super classes - quitting"); } cfMapDef.setCfBaseMapDef(cfBaseMapDef); } }
private <T> void validateDerivedEntityClass(ClassCacheMgr cacheMgr, CFMappingDef<T> cfMapDef) { findAndSetBaseClassViaMappings(cacheMgr, cfMapDef); if (null == cfMapDef.getCfBaseMapDef()) { throw new HectorObjectMapperException("@" + Table.class.getSimpleName() + " used by class, " + cfMapDef.getRealClass().getName() + ", " + " has already been specified by base class, " + cfMapDef.getCfBaseMapDef().getEffectiveClass().getName()); } }
private <T> void setComplexId(CFMappingDef<T> cfMapDef, T obj, Object pkObj) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { KeyDefinition keyDef = cfMapDef.getKeyDef(); if (!pkObj.getClass().equals(keyDef.getPkClazz())) { throw new HectorObjectMapperException("primary key object, " + pkObj.getClass().getName() + ", must be of type " + keyDef.getPkClazz().getName()); } for (PropertyDescriptor pd : keyDef.getPropertyDescriptorMap().values()) { PropertyMappingDefinition md = keyDef.getIdPropertyMap().get(pd.getName()); if (null == md) { throw new HectorObjectMapperException("Trying to set complex key type, but field, " + pd.getName() + ", is not annotated with @" + Id.class.getSimpleName() + " in POJO, " + cfMapDef.getRealClass().getName()); } Method meth = md.getPropDesc().getWriteMethod(); if (null == meth) { logger.debug("@Id annotation found - but can't find setter for property, " + md.getPropDesc().getName()); } meth.invoke(obj, pd.getReadMethod().invoke(pkObj, (Object[]) null)); } }
private <T> void validateSingleTableInheritance(CFMappingDef<T> cfMapDef) { // validating the base class in an inheritance hierarchy. must have a // discriminator column defined if (null == cfMapDef.getDiscColumn()) { throw new HectorObjectMapperException("Class, " + cfMapDef.getRealClass().getName() + ", requested single table inheritance, but you did not specify a " + DiscriminatorColumn.class.getSimpleName() + " annotation"); } // if it is abstract, cannot be instantiated and therefore should not have a // discriminator value defined if (cfMapDef.isAbstract() && null != cfMapDef.getDiscValue()) { throw new HectorObjectMapperException("Abstract class, " + cfMapDef.getRealClass().getName() + ", has an @" + DiscriminatorValue.class.getSimpleName() + " annotation, but cannot be instantiated"); } else if (!cfMapDef.isAbstract() && null == cfMapDef.getDiscValue()) { throw new HectorObjectMapperException("Class, " + cfMapDef.getEffectiveClass().getName() + ", is a part of inheritance hierarchy, but did not specify a " + DiscriminatorValue.class.getSimpleName() + " annotation. Should it be 'abstract'?"); } }
@Override public <T> void validateAndSetDefaults(ClassCacheMgr cacheMgr, CFMappingDef<T> cfMapDef) { KeyDefinition keyDef = cfMapDef.getKeyDef(); if ( null == keyDef.getPkClazz() ) { return; } Map<String, PropertyDescriptor> pdMap; try { pdMap = cacheMgr.getFieldPropertyDescriptorMap(keyDef.getPkClazz()); } catch (IntrospectionException e) { throw new HectorObjectMapperException("exception while introspecting class, " + keyDef.getPkClazz().getName(), e); } if ( keyDef.getIdPropertyMap().size() != pdMap.size() ) { throw new HectorObjectMapperException("Each field in the primary key class, " + keyDef.getPkClazz().getName() + ", must have a corresponding property in the entity, " + cfMapDef.getRealClass().getName() + ", annotated with @" + Id.class.getSimpleName() ); } for ( String idFieldName : pdMap.keySet() ) { if ( !keyDef.getIdPropertyMap().containsKey(idFieldName)) { throw new HectorObjectMapperException("Each field in the primary key class, " + keyDef.getPkClazz().getName() + ", must have a corresponding property in the entity, " + cfMapDef.getRealClass().getName() + ", annotated with @" + Id.class.getSimpleName() + " : missing ID field, " + idFieldName); } } }
@SuppressWarnings("unchecked") private <T> void addAnonymousProperties(T obj, CFMappingDef<T> cfMapDef, Map<String, HColumn<String, byte[]>> colSet) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { Method meth = cfMapDef.getAnonymousPropertyGetHandler(); if (null == meth) { return; } Collection<Entry<String, Object>> propColl = (Collection<Entry<String, Object>>) meth.invoke( obj, (Object[]) null); if (null == propColl || propColl.isEmpty()) { return; } for (Entry<String, Object> entry : propColl) { if (!(entry.getKey() instanceof String) || !entry.getValue().getClass().equals(cfMapDef.getAnonymousValueType())) { throw new HectorObjectMapperException("Class, " + cfMapDef.getRealClass() + ", anonymous properties must have entry.key of type, " + String.class.getName() + ", and entry.value of type, " + cfMapDef.getAnonymousValueType().getName() + ", to properly map to Cassandra column name/value"); } } for (Entry<String, Object> entry : propColl) { colSet.put( entry.getKey(), HFactory.createColumn(entry.getKey(), cfMapDef.getAnonymousValueSerializer().toBytes(entry.getValue()), StringSerializer.get(), BytesArraySerializer.get())); } }
} catch (Throwable e) { throw new HectorObjectMapperException( "exception while instantiating anonymous converter for class, " + cfMapDef.getRealClass() + ", with converter type, " + anno.serializer(), e); addMeth = cfMapDef.getRealClass().getMethod(anno.adder(), String.class, anno.type()); } catch (NoSuchMethodException e) { throw new HectorObjectMapperException("Could not find anonymous add handler for class, " + cfMapDef.getRealClass() + ", with anonymous value type, " + anno.type()); } catch (Throwable e) { throw new HectorObjectMapperException( "exception while finding anonymous add handler for class, " + cfMapDef.getRealClass() + ", with anonymous value type, " + anno.type(), e); getMeth = cfMapDef.getRealClass().getMethod(anno.getter()); } catch (NoSuchMethodException e) { throw new HectorObjectMapperException("Could not find anonymous get handler for class, " + cfMapDef.getRealClass()); } catch (Throwable e) { throw new HectorObjectMapperException( "exception while finding anonymous get handler for class, " + cfMapDef.getRealClass());
cfMapByClazz.put(cfMapDef.getRealClass(), cfMapDef);
@Test public void testInheritanceOfEntity() { ClassCacheMgr cacheMgr = new ClassCacheMgr(); CFMappingDef<MyRedTestBean> cfMapDef = cacheMgr.initializeCacheForClass(MyRedTestBean.class); // 13 is valid when custom conversion of enumerations works again // don't like hard coding numbers into JUnits, but took easy way for now assertEquals(14, cfMapDef.getAllProperties().size()); assertNotNull(cfMapDef.getCfBaseMapDef()); assertEquals(MyRedTestBean.class, cfMapDef.getEffectiveClass()); assertEquals("TestBeanColumnFamily", cfMapDef.getEffectiveColFamName()); assertEquals("myType", cfMapDef.getDiscColumn()); assertEquals(DiscriminatorType.STRING, cfMapDef.getDiscType()); assertEquals("baseId", cfMapDef.getKeyDef().getIdPropertyMap().values().iterator().next() .getPropDesc().getName()); // check super class settings assertEquals( MyRedTestBean.class.getSuperclass(), cfMapDef.getCfSuperMapDef().getRealClass()); assertFalse( cfMapDef.getCfSuperMapDef().isColumnSliceRequired()); }