Hibernate 不允许我处理错误凭据的异常

Hibernate do not let me handle exception on wrong credentials

首先我要说的是,我尝试了很多关于这个主题的资料,但找不到任何对此事有帮助的文件。如果我遗漏了什么,我提前道歉。

我使用带 Hibernate 5.4 和 JavaFX 的 Eclipse 来管理桌面应用程序,该应用程序将要求用户以交互方式提供数据库凭据,并使用该信息覆盖休眠上的 属性-cfg.xml 文件。这部分正在全面运作。 当我想处理用户提供错误凭据的极有可能情况时,我的问题就来了。看起来休眠不允许我处理我在代码中使用的任何异常。

有人可以看看并建议我应该改进哪些地方以便能够处理这些问题吗?

这是我的代码,我将在其中尝试使用用户提供的信息构建 sectionFactory。我希望在 task.setOnFailed 上处理错误凭据的事件,但从未调用过,无论发生什么 task.setOnSucceeded 总是被调用。

    //Task to connect to DB
private void taskDBConnection() {

    // Create a background Task
    Task<Void> task = new Task<Void>() {
        @Override
        protected Void call() throws Exception {

            actionTarget.setText("Attempt to login to database");

            HibernateUtil.getSessionFactory();

            return null;
        }
    };

    // This method allows us to handle any Exceptions thrown by the task
    task.setOnFailed(new EventHandler<WorkerStateEvent>() {
        @Override
        public void handle(WorkerStateEvent arg0) {
            System.out.println("Failed LoginView.java setOnFailed");
            task.getException().printStackTrace();
        }
    });

    // If the task completed successfully, perform other updates here
    task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
        @Override
        public void handle(WorkerStateEvent arg0) {
            System.out.println("Done LoginView.java setOnSucceeded");

            loginStage.close();
        }
    });

    // Now, start the task on a background thread
    new Thread(task).start();
}

这是我的 sessionFactory 构建器 class,同样,那里的 catch 异常从未被调用。

    public static SessionFactory getSessionFactory() {
    if (sessionFactory == null) {
        try {

            //Create the config file / legacy but still works
            Configuration hibernateConfig = new Configuration().configure(new File(Paths.get("").toAbsolutePath().toString() + "\Config\hibernate.cfg.xml"));
            hibernateConfig.setProperty("hibernate.connection.username", getUsername());
            hibernateConfig.setProperty("hibernate.connection.password", getPassword());

            // Creating a registry
            //registry = new StandardServiceRegistryBuilder().configure(new File(Paths.get("").toAbsolutePath().toString() + "\Config\hibernate.cfg.xml")).build();
            registry = new StandardServiceRegistryBuilder().applySettings(hibernateConfig.getProperties()).build();

            // Create the MetadataSources
            MetadataSources sources = new MetadataSources(registry);
            sources.addAnnotatedClass(Class1.class);
            sources.addAnnotatedClass(Class2.class);

            // Create the Metadata
            Metadata metadata = sources.getMetadataBuilder().build();

            // Create SessionFactory
            sessionFactory = metadata.getSessionFactoryBuilder().build();

        } catch (Exception e) {
            e.printStackTrace();

            if (registry != null) {
                StandardServiceRegistryBuilder.destroy(registry);
            }
        }
    }

    return sessionFactory;
}

以下是我在 Eclipse 上遇到的错误。它很长,所以我只 post 第一部分。我当然知道异常是什么(我强迫它发生),但我想以一种方式处理它,通知用户他们不正确并允许他们重试。

WARNING: com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@87315ad -- Acquisition Attempt Failed!!! Clearing pending acquires. While trying to acquire a needed new resource, we failed to succeed more than the maximum number of allowed acquisition attempts (1). Last acquisition attempt exception: 
java.sql.SQLException: ORA-01017: invalid username/password; logon denied

    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:392)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:385)
    at oracle.jdbc.driver.T4CTTIfun.processError(T4CTTIfun.java:1018)
    at oracle.jdbc.driver.T4CTTIoauthenticate.processError(T4CTTIoauthenticate.java:501)
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:522)
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:257)
    at oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:437)
    at oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:954)
    at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:639)
    at oracle.jdbc.driver.PhysicalConnection.connect(PhysicalConnection.java:666)
    at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
    at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:566)
    at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:175)
    at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:220)
    at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:206)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPoolPooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:203)
    at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1138)
    at com.mchange.v2.resourcepool.BasicResourcePool.doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess(BasicResourcePool.java:1125)
    at com.mchange.v2.resourcepool.BasicResourcePool.access0(BasicResourcePool.java:44)
    at com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask.run(BasicResourcePool.java:1870)
    at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:696)

然后休眠。cfg.xml

    <session-factory>

        <property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
        <property name="connection.url">jdbc:oracle:thin:@database:1521:schema</property>
        <property name="dialect">org.hibernate.dialect.Oracle8iDialect</property>
        <property name="show_sql">true</property>

        <property name="hibernate.c3p0.min_size">5</property>
        <property name="hibernate.c3p0.max_size">20</property>
        <property name="hibernate.c3p0.timeout">1800</property>
        <property name="hibernate.c3p0.max_statements">50</property>
        <property name="hibernate.c3p0.acquireRetryAttempts">1</property>
        <property name="hibernate.c3p0.acquireRetryDelay">2500</property>

    </session-factory>

万一有人好奇,我通过处理任何抛出的异常并在我的应用程序的标签中打印此消息,设法使它或多或少地按我想要的方式工作。 我将始终通过使用 Optional 对其进行迭代来获得根异常,因此当它是错误的凭据时,JDBC 会将其作为结果。

catch (Exception e) {
        Optional<Throwable> rootCause = Stream.iterate(e, Throwable::getCause)
                .filter(element -> element.getCause() == null)
                .findFirst();
        System.out.println(rootCause.get().getClass().getSimpleName() + " - " + rootCause.get().getMessage());}