initProperties();
Class<?> idClass = getCompositeKeyClass();
Object id = idClass.newInstance();
PropertyDescriptor[] idProperties = PropertyUtils.getPropertyDescriptors(idClass);
if(idProperties == null || idProperties.length == 0)
throw new UnexpectedException("Composite id has no properties: "+idClass.getName());
for (PropertyDescriptor idProperty : idProperties) {
// do we have a field for this?
String idPropertyName = idProperty.getName();
// skip the "class" property...
if(idPropertyName.equals("class"))
continue;
Model.Property modelProperty = this.properties.get(idPropertyName);
if(modelProperty == null)
throw new UnexpectedException("Composite id property missing: "+clazz.getName()+"."+idPropertyName
+" (defined in IdClass "+idClass.getName()+")");
// sanity check
Object value = modelProperty.field.get(model);
if(modelProperty.isMultiple)
throw new UnexpectedException("Composite id property cannot be multiple: "+clazz.getName()+"."+idPropertyName);
// now is this property a relation? if yes then we must use its ID in the key (as per specs)
if(modelProperty.isRelation){
// get its id
if(!Model.class.isAssignableFrom(modelProperty.type))
throw new UnexpectedException("Composite id property entity has to be a subclass of Model: "
+clazz.getName()+"."+idPropertyName);
// we already checked that cast above
@SuppressWarnings("unchecked")
Model.Factory factory = Model.Manager.factoryFor((Class<? extends Model>) modelProperty.type);
if(factory == null)
throw new UnexpectedException("Failed to find factory for Composite id property entity: "
+clazz.getName()+"."+idPropertyName);
// we already checked that cast above
if(value != null)
value = factory.keyValue((Model) value);
}