docs: private void checkReferenceForeignkeys(ModelDef modelDef, ReferenceDescriptorDef refDef) throws ConstraintException
      {
          String foreignkey = refDef.getProperty(PropertyHelper.OJB_PROPERTY_FOREIGNKEY);
  
          if ((foreignkey == null) || (foreignkey.length() == 0))
          {
              throw new ConstraintException("The reference "+refDef.getName()+" in class "+refDef.getOwner().getName()+" has no foreignkeys");
          }
  
          // we know that the class is present because the reference constraints have been checked already
          ClassDescriptorDef ownerClass = (ClassDescriptorDef)refDef.getOwner();
          ArrayList          keyFields;
          FieldDescriptorDef keyField;
          
          try
          {
              keyFields = ownerClass.getFields(foreignkey);
          }
          catch (NoSuchFieldException ex)
          {
              throw new ConstraintException("The reference "+refDef.getName()+" in class "+refDef.getOwner().getName()+" specifies a foreignkey "+ex.getMessage()+" that is not a persistent field in its owner class "+ownerClass.getName());
          }
          for (int idx = 0; idx < keyFields.size(); idx++)
          {
              keyField = (FieldDescriptorDef)keyFields.get(idx);
              if (keyField.getBooleanProperty(PropertyHelper.OJB_PROPERTY_IGNORE, false))
              {
                  throw new ConstraintException("The reference "+refDef.getName()+" in class "+ownerClass.getName()+" uses the field "+keyField.getName()+" as foreignkey although this field is ignored in this class");
              }
          }
              
          // for the referenced class and any subtype that is instantiable (i.e. not an interface or abstract class)
          // there must be the same number of primary keys and the jdbc types of the primary keys must
          // match the jdbc types of the foreignkeys (in the correct order)
          String             targetClassName = refDef.getProperty(PropertyHelper.OJB_PROPERTY_CLASS_REF);
          ArrayList          queue           = new ArrayList();
          ClassDescriptorDef referencedClass;
          ArrayList          primFields;
          FieldDescriptorDef primField;
          String             primType;
          String             keyType;
          
          queue.add(modelDef.getClass(targetClassName));
  
          while (!queue.isEmpty())
          {
              referencedClass = (ClassDescriptorDef)queue.get(0);
              queue.remove(0);
  
              for (Iterator it = referencedClass.getExtentClasses(); it.hasNext();)
              {
                  queue.add(it.next());
              }
              if (!referencedClass.getBooleanProperty(PropertyHelper.OJB_PROPERTY_GENERATE_REPOSITORY_INFO, true))
              {
                  continue;
              }
              primFields = referencedClass.getPrimaryKeys();
              if (primFields.size() != keyFields.size())
              {
                  throw new ConstraintException("The number of foreignkeys ("+keyFields.size()+") of the reference "+refDef.getName()+" in class "+refDef.getOwner().getName()+" doesn't match the number of primarykeys ("+primFields.size()+") of the referenced class (or its subclass) "+referencedClass.getName());
              }
              for (int idx = 0; idx < primFields.size(); idx++)
              {
                  keyField  = (FieldDescriptorDef)keyFields.get(idx);
                  primField = (FieldDescriptorDef)primFields.get(idx);
                  primType  = primField.getProperty(PropertyHelper.OJB_PROPERTY_JDBC_TYPE);
                  keyType   = keyField.getProperty(PropertyHelper.OJB_PROPERTY_JDBC_TYPE);
                  if (!primType.equals(keyType))
                  {
                      throw new ConstraintException("The jdbc-type of foreignkey "+keyField.getName()+" of the reference "+refDef.getName()+" in class "+refDef.getOwner().getName()+" doesn't match the jdbc-type of the corresponding primarykey "+primField.getName()+" of the referenced class (or its subclass) "+referencedClass.getName());
                  }
              }
          }
      }