Reputation: 371
is there any way to loop (e.g. via for) all classes with are in some package?
I have to addAnnotatedClass(Class c)
on AnnotationConfiguration
.
Doing it like this:
AnnotationConfiguration annotationConfiguration.addAnnotatedClass(AdditionalInformation.class);
annotationConfiguration.addAnnotatedClass(AdditionalInformationGroup.class);
annotationConfiguration.addAnnotatedClass(Address.class);
annotationConfiguration.addAnnotatedClass(BankAccount.class);
annotationConfiguration.addAnnotatedClass(City.class);
//et cetera
All of my tables are in package Tables.Informations
.
Upvotes: 12
Views: 40135
Reputation: 1
For Hibernate 6.* versions, the way to implement this one is:
public class HibernateUtils {
private static SessionFactory sessionFactory;
static {
try {
Properties props = new Properties();
props.load(HibernateUtils.class.getClassLoader().getResourceAsStream("hibernate.properties"));
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(props)
.build();
MetadataSources metadataSources = new MetadataSources(serviceRegistry);
Reflections reflections = new Reflections("io.github.gustavo.model");
Set<Class<?>> entityClasses = reflections.getTypesAnnotatedWith(Entity.class);
entityClasses.forEach(metadataSources::addAnnotatedClass);
Metadata metadata = metadataSources.getMetadataBuilder().build();
sessionFactory = metadata.getSessionFactoryBuilder().build();
} catch(Exception e) {
throw new ExceptionInInitializerError("Falha ao inicializar a Session Factory");
}
}
lib reflections:
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.10.2</version>
</dependency>
Upvotes: 0
Reputation: 668
There is a nice open source package called "org.reflections". You can find it here: https://github.com/ronmamo/reflections
Using that package, you can scan for entities like this:
Reflections reflections = new Reflections("Tables.Informations");
Set<Class<?>> importantClasses = reflections.getTypesAnnotatedWith(Entity.class);
for (Class<?> clazz : importantClasses) {
configuration.addAnnotatedClass(clazz);
}
Upvotes: 5
Reputation: 101
You can use LocalSessionFactoryBuilder for building session factory that enables you to specify scanPackages property.
SessionFactory sessionFactory = new LocalSessionFactoryBuilder(hikariDataSource())
.scanPackages("com.animals.entities")
.addProperties(properties)
.buildSessionFactory();
Upvotes: 2
Reputation: 7374
The following code goes through all the classes within a specified package and makes a list of those annotated with "@Entity". Each of those classes is added into your Hibernate factory configuration, without having to list them all explicitly.
public static void main(String[] args) throws URISyntaxException, IOException, ClassNotFoundException {
try {
Configuration configuration = new Configuration().configure();
for (Class cls : getEntityClassesFromPackage("com.example.hib.entities")) {
configuration.addAnnotatedClass(cls);
}
sessionFactory = configuration.buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static List<Class<?>> getEntityClassesFromPackage(String packageName) throws ClassNotFoundException, IOException, URISyntaxException {
List<String> classNames = getClassNamesFromPackage(packageName);
List<Class<?>> classes = new ArrayList<Class<?>>();
for (String className : classNames) {
Class<?> cls = Class.forName(packageName + "." + className);
Annotation[] annotations = cls.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(cls.getCanonicalName() + ": " + annotation.toString());
if (annotation instanceof javax.persistence.Entity) {
classes.add(cls);
}
}
}
return classes;
}
public static ArrayList<String> getClassNamesFromPackage(String packageName) throws IOException, URISyntaxException, ClassNotFoundException {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
ArrayList<String> names = new ArrayList<String>();
packageName = packageName.replace(".", "/");
URL packageURL = classLoader.getResource(packageName);
URI uri = new URI(packageURL.toString());
File folder = new File(uri.getPath());
File[] files = folder.listFiles();
for (File file: files) {
String name = file.getName();
name = name.substring(0, name.lastIndexOf('.')); // remove ".class"
names.add(name);
}
return names;
}
Helpful reference: https://stackoverflow.com/a/7461653/7255
Upvotes: 13
Reputation: 15229
As mentioned in the comments, the functionality of loading all classes in a package is not possible with the AnnotationConfiguration API. Here's some of the stuff you can do with said API (note that the "addPackage" method only reads package metadata, such as that found in the package-info.java class, it does NOT load all classes in package):
http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/ch01.html
sessionFactory = new AnnotationConfiguration()
.addPackage("test.animals") //the fully qualified package name
.addAnnotatedClass(Flight.class)
.addAnnotatedClass(Sky.class)
.addAnnotatedClass(Person.class)
.addAnnotatedClass(Dog.class)
.addResource("test/animals/orm.xml")
.configure()
.buildSessionFactory();
Upvotes: 14