Files
netneutrality/src/main/java/me/bobert/netneutrality/db/SessionManager.java
T
anthorob 677b3f8013 Remove JpaUtils and refactor repository access
Eliminated the static `JpaUtils` utility and transitioned to explicit repository management for improved modularity and testability. Updated `GuildService`, `TaskManagerImpl`, and related classes to use dependency-injected repositories. Simplified configuration by aligning repository definitions with existing service patterns and ensuring proper session handling through `SessionManager`. Verified that all affected components function as expected after refactoring.
2026-09-25 12:17:19 -04:00

112 lines
3.6 KiB
Java

package me.bobert.netneutrality.db;
/*
* Copyright (c) anthorob
*
* https://discord.gg/qUa6zNFZsd
*/
import io.sentry.Sentry;
import me.bobert.netneutrality.utils.SettingsProvider;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Environment;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* Instance-based {@link SessionProvider} owning the Hibernate {@link SessionFactory} and its
* service registry.
*
* <p>{@link #start()} first applies the Flyway migrations and only then builds the session factory,
* which validates the mapped entities against the migrated schema ({@code hbm2ddl.auto=validate}).
*/
public class SessionManager implements SessionProvider {
private static final Logger logger = LogManager.getLogger(SessionManager.class);
private final DatabaseConfig config;
private final boolean reportErrors;
private StandardServiceRegistry registry;
private volatile SessionFactory sessionFactory;
public SessionManager(SettingsProvider settings) {
this(DatabaseConfig.from(settings), !"dev".equals(settings.get("NETNEUTRALITY_BOT_ENV", "dev")));
}
/**
* @param config the database connection settings
* @param reportErrors whether startup failures are reported to Sentry
*/
public SessionManager(DatabaseConfig config, boolean reportErrors) {
this.config = Objects.requireNonNull(config, "config");
this.reportErrors = reportErrors;
}
@Override
public int priority() {
return 10;
}
@Override
public synchronized void start() {
if (sessionFactory != null) {
return;
}
try {
logger.info("Connecting to database '{}' with user '{}'", config.url(), config.user());
DatabaseMigration.migrate(config);
sessionFactory = buildSessionFactory();
} catch (RuntimeException e) {
if (reportErrors) {
Sentry.captureException(e);
}
stop();
logger.error("Error connecting to database. Shutting down..", e);
throw new IllegalStateException("Unable to connect to the database", e);
}
}
private SessionFactory buildSessionFactory() {
Map<String, Object> settings = new HashMap<>();
settings.put(Environment.JAKARTA_JDBC_URL, config.url());
settings.put(Environment.JAKARTA_JDBC_USER, config.user());
settings.put(Environment.JAKARTA_JDBC_PASSWORD, config.password());
registry = new StandardServiceRegistryBuilder()
.configure()
.applySettings(settings)
.build();
return new MetadataSources(registry).buildMetadata().buildSessionFactory();
}
@Override
public synchronized void stop() {
SessionFactory factory = sessionFactory;
sessionFactory = null;
if (factory != null) {
factory.close();
}
if (registry != null) {
StandardServiceRegistryBuilder.destroy(registry);
registry = null;
}
}
@Override
public SessionFactory getSessionFactory() {
SessionFactory factory = sessionFactory;
if (factory == null) {
throw new IllegalStateException("SessionManager has not been started");
}
return factory;
}
}