Вы формулируете условие вашей задачи так, что она становится бессмысленной. Причина простая: статика и наследование не пересекаются от слова совсем. Разумеется, невыполнимых задач нет. И если уж из статики вы никак не можете обратиться к нестатическим методам и полям, то наоборот это вполне возможно. Если предположить, что для всех сущностей у вас будет единственный супер класс (чтобы в этом был хоть какой-то смысл), то можно сделать примерно так:
abstract class BaseEntity {
private final static String BASE_PACKAGE_NAME = "base.package.name";
private final static String SCHEMA_NAME_DELIMETER = ".";
private final static Map<Class, String> MAP = scan();
public String getTableName() {
return MAP.get(this.getClass());
}
private static Map<Class, String> scan() {
Map<Class, String> result = new HashMap<>();
Set<Class<?>> classes = new Reflections(BASE_PACKAGE_NAME).getTypesAnnotatedWith(Table.class);
for (Class clazz : classes) {
Table annotation = (Table) clazz.getAnnotation(Table.class);
if (annotation == null) continue;
String tableName = annotation.schema().isEmpty() ?
annotation.name() : annotation.schema() + SCHEMA_NAME_DELIMETER + annotation.name();
result.put(clazz, tableName);
}
return result;
}
}
@Table(schema = "test_schema", name = "b_name")
class A extends BaseEntity{}
@Table(name = "b_name")
class B extends BaseEntity{}
Лично для меня это выглядит как костыль))
Даже если что-то подобное нужно реализовать, то уж точно этого не нужно делать в супер классе. Гораздо проще и логичнее делинировать это стороннему классу, который просканирует весь проект на старте, подготовит все данные и будет единым источником, где это можно запросить для любого объекта.
Кроме того, можно 2навешать" перегруженные методы (в зависимоти от задачи), где, к примеру, будет подставляться дефолтная схема в случае ее отсутствия в аннотации.
Выглядит это примерно так:
import com.geeks.rea.model.History;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javax.persistence.Table;
import org.reflections.Reflections;
public class ReflectionUtil {
private final static String BASE_PACKAGE_NAME = "base.package.name";
private final static String SCHEMA_NAME_DELIMETER = ".";
private final static Map<Class, String> MAP = scan();
public static void main(String[] args) {
System.out.println(getTableName(History.class));
}
public static Optional<String> getTableName(Object entity) {
return Optional.ofNullable(MAP.get(entity.getClass()));
}
public static Optional<String> getTableName(Object entity, String defaultSchemaName) {
if (defaultSchemaName == null || defaultSchemaName.trim().isEmpty()) {
throw new RuntimeException("Default schemas name can't be NULL");
}
else return getTableName(entity).map(name -> name.contains(SCHEMA_NAME_DELIMETER) ?
name : defaultSchemaName.trim() + SCHEMA_NAME_DELIMETER + name);
}
private static Map<Class, String> scan() {
Map<Class, String> result = new HashMap<>();
Set<Class<?>> classes = new Reflections(BASE_PACKAGE_NAME).getTypesAnnotatedWith(Table.class);
for (Class clazz : classes) {
Table annotation = (Table) clazz.getAnnotation(Table.class);
if (annotation == null) continue;
String tableName = annotation.schema().isEmpty() ?
annotation.name() : annotation.schema() + SCHEMA_NAME_DELIMETER + annotation.name();
result.put(clazz, tableName);
}
return result;
}
}
P.S. для упрощения реализации рефлексии использовалась библиотека, которую можно найти здесь:
https://mvnrepository.com/artifact/org.reflections/reflections
Не забудьте указать в переменной BASE_PACKAGE_NAME базовое имя своего пакета