no

How to Get Classes that Referenced a Given Entity in Hibernate

There are times when we want to list the entities that referenced (via foreign keys) a given entity x. For example, when deleting entity x t...

There are times when we want to list the entities that referenced (via foreign keys) a given entity x. For example, when deleting entity x that is being referenced, it will throw a generic ConstraintViolationException. Oftentimes, we need to display this classes. This is how we do it:
/**
 * Map of classes and classes and fields that contains the referenced class.
 */
private static Map<Class, Map<Class, List<Field>>> classReferences = new HashMap<>();

/**
 * Determines a generic type of a field. For example: List<String> field should return String).
 */
public static Class getFieldGenericsType(Field field) {
 if (field.getGenericType() instanceof ParameterizedType) {
  ParameterizedType aType = (ParameterizedType) field.getGenericType();
  Type[] fieldArgTypes = aType.getActualTypeArguments();
  
  for (Type fieldArgType : fieldArgTypes) {
   Class fieldArgClass = (Class) fieldArgType;
   return fieldArgClass;
  }
 }
 
 return null;
}

/**
 * Gets all the declared fields of a given class.
 **/
public static List<Field> getAllFields(List<Field> fields, Class<?> type) {
 fields.addAll(Arrays.asList(type.getDeclaredFields()));

 if (type.getSuperclass() != null) {
  fields = getAllFields(fields, type.getSuperclass());
 }

 return fields;
}

/**
 * Gets all the classes that referenced a given class.
 */
public static Map<Class, List<Field>> getReferencedClassesAndFieldsOfType(Class fieldClass) {

 if (classReferences.containsKey(fieldClass)) {
  return classReferences.get(fieldClass);
 }

 Class superClass = fieldClass.getSuperclass();

 Map<Class, List<Field>> matchedFields = new HashMap<>();

 Reflections reflections = new Reflections("com.broodcamp.model");
 // gets all our entity classes in our project
 Set<Class<? extends BaseEntity>> classes = reflections.getSubTypesOf(BaseEntity.class);

 // loop thru
 for (Class<? extends BaseEntity> clazz : classes) {
  // we are not interested with either interface or abstract
  if (clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers())) {
   continue;
  }
  
  // gets all the fields of a given class
  List<Field> fields = getAllFields(new ArrayList<Field>(), clazz);
 
  // loops thru the fields
  for (Field field : fields) {

   // we are not interested with transient field
   if (field.isAnnotationPresent(Transient.class)) {
    continue;
   }
   
   // filter the field or parametized field of type fieldClass
   // this means it refer to our referenced class
   if (field.getType() == fieldClass || (Collection.class.isAssignableFrom(field.getType()) && getFieldGenericsType(field) == fieldClass) || (superClass != null
     && (field.getType() == superClass || (Collection.class.isAssignableFrom(field.getType()) && getFieldGenericsType(field) == superClass)))) {

    // add to map
    if (!matchedFields.containsKey(clazz)) {
     matchedFields.put(clazz, new ArrayList<>());
    }
    matchedFields.get(clazz).add(field);
   }
  }
 }
 classReferences.put(fieldClass, matchedFields);
 
 return matchedFields;
}

Related

persistence 2350403673228791468

Post a Comment Default Comments

item