Merge pull request #10 from gmbrax/refactor/add-hibernate-and-reflection-dependency

Remove `Media` entity and integrate Hibernate ORM into `DatabaseManager`:
This commit is contained in:
Gustavo Henrique Miranda 2025-11-28 00:38:21 -03:00 committed by GitHub
commit ba53d4d8c4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 102 additions and 130 deletions

11
pom.xml
View File

@ -35,6 +35,12 @@
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-community-dialects</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- HikariCP for connection pooling -->
<dependency>
<groupId>com.zaxxer</groupId>
@ -88,6 +94,11 @@
<artifactId>sqlite-jdbc</artifactId>
<version>3.44.1.0</version>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.10.2</version>
</dependency>
</dependencies>
<build>

View File

@ -1,128 +0,0 @@
package com.mediamanager.model;
import jakarta.persistence.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "media")
public class Media {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String title;
@Column(nullable = false, unique = true)
private String filePath;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private MediaType type;
@Column
private Long fileSize;
@Column
private String mimeType;
@Column(name = "created_at", nullable = false, updatable = false)
private LocalDateTime createdAt;
@Column(name = "updated_at")
private LocalDateTime updatedAt;
@PrePersist
protected void onCreate() {
createdAt = LocalDateTime.now();
updatedAt = LocalDateTime.now();
}
@PreUpdate
protected void onUpdate() {
updatedAt = LocalDateTime.now();
}
// Constructors
public Media() {}
public Media(String title, String filePath, MediaType type) {
this.title = title;
this.filePath = filePath;
this.type = type;
}
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public MediaType getType() {
return type;
}
public void setType(MediaType type) {
this.type = type;
}
public Long getFileSize() {
return fileSize;
}
public void setFileSize(Long fileSize) {
this.fileSize = fileSize;
}
public String getMimeType() {
return mimeType;
}
public void setMimeType(String mimeType) {
this.mimeType = mimeType;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}
public LocalDateTime getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
}
public enum MediaType {
VIDEO,
AUDIO,
IMAGE,
DOCUMENT,
OTHER
}
}

View File

@ -1,16 +1,26 @@
package com.mediamanager.service.database;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.cfg.Configuration;
import org.reflections.Reflections;
import org.reflections.scanners.Scanners;
import jakarta.persistence.Entity;
import java.util.Set;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public abstract class DatabaseManager {
protected final Properties configuration;
protected Connection connection;
protected String connectionUrl;
protected EntityManagerFactory entityManagerFactory;
protected EntityManager entityManager;
protected static final Logger logger = LogManager.getLogger(DatabaseManager.class);
public DatabaseManager(Properties config) {
@ -38,6 +48,22 @@ public abstract class DatabaseManager {
}
public void close() {
if (entityManager != null && entityManager.isOpen()) {
try {
entityManager.close();
logger.info("EntityManager closed");
} catch (Exception e) {
logger.error("Error closing EntityManager: {}", e.getMessage());
}
}
if (entityManagerFactory != null && entityManagerFactory.isOpen()) {
try {
entityManagerFactory.close();
logger.info("EntityManagerFactory closed");
} catch (Exception e) {
logger.error("Error closing EntityManagerFactory: {}", e.getMessage());
}
}
if (connection != null) {
try {
logger.info("Closing database connection...");
@ -50,6 +76,7 @@ public abstract class DatabaseManager {
logger.debug("No database connection to close");
}
}
protected boolean testConnection() {
try (Statement stmt = connection.createStatement()) {
stmt.execute("SELECT 1");
@ -59,4 +86,64 @@ public abstract class DatabaseManager {
return false;
}
}
protected void initializeHibernate() {
logger.info("Initializing Hibernate ORM...");
Configuration hibernateConfig = new Configuration();
String dialect = configuration.getProperty("hibernate.dialect");
String hbm2ddl = configuration.getProperty("hibernate.hbm2ddl.auto");
String driver = configuration.getProperty("database.driver");
if (dialect == null || dialect.isEmpty()) {
throw new IllegalStateException("hibernate.dialect property is required but not configured");
}
if (driver == null || driver.isEmpty()) {
throw new IllegalStateException("database.driver property is required but not configured");
}
if (connectionUrl == null || connectionUrl.isEmpty()) {
throw new IllegalStateException("connectionUrl must be set before initializing Hibernate");
}
hibernateConfig.setProperty("hibernate.connection.url", connectionUrl);
hibernateConfig.setProperty("hibernate.connection.driver_class", driver);
hibernateConfig.setProperty("hibernate.dialect", dialect);
hibernateConfig.setProperty("hibernate.hbm2ddl.auto", hbm2ddl);
hibernateConfig.setProperty("hibernate.show_sql",
configuration.getProperty("hibernate.show_sql", "false"));
hibernateConfig.setProperty("hibernate.format_sql",
configuration.getProperty("hibernate.format_sql", "true"));
logger.info("Scanning for entities in package: com.mediamanager.model");
Set<Class<?>> entityClasses;
try {
Reflections reflections = new Reflections("com.mediamanager.model", Scanners.TypesAnnotated);
entityClasses = reflections.getTypesAnnotatedWith(Entity.class);
} catch (Exception e) {
logger.error("Failed to scan for entities: {}", e.getMessage());
throw new RuntimeException("Entity scanning failed", e);
}
logger.info("Found {} entities", entityClasses.size());
if (entityClasses.isEmpty()) {
logger.warn("No @Entity classes found in package com.mediamanager.model - is this expected?");
}
for (Class<?> entityClass : entityClasses) {
logger.debug("Registering entity: {}", entityClass.getSimpleName());
hibernateConfig.addAnnotatedClass(entityClass);
}
try {
entityManagerFactory = hibernateConfig.buildSessionFactory().unwrap(EntityManagerFactory.class);
entityManager = entityManagerFactory.createEntityManager();
} catch (Exception e) {
logger.error("Failed to initialize Hibernate: {}", e.getMessage());
throw new RuntimeException("Hibernate initialization failed", e);
}
logger.info("Hibernate ORM initialized successfully");
}
}

View File

@ -16,7 +16,7 @@ public class SqliteDatabaseManager extends DatabaseManager {
private static final Logger logger = LogManager.getLogger(SqliteDatabaseManager.class);
private String connectionUrl;
public SqliteDatabaseManager(Properties config) {
super(config);
@ -45,12 +45,14 @@ public class SqliteDatabaseManager extends DatabaseManager {
this.connectionUrl = "jdbc:sqlite:" + dbFile.toAbsolutePath().toString();
logger.info("Database file path: {}", dbFile);
logger.info("Connection URL: {}", this.connectionUrl);
initializeHibernate();
this.connection = createConnection();
configurePerformancePragmas();
performSanityChecks();
ensureSchemaExists();
logger.info("SQLite database initialized successfully");
}
@Override