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...
https://www.czetsuyatech.com/2017/12/hibernate-referenced-entity.html
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; }
Post a Comment