在使用 OpenJPA 时调用 createEntityManager 时,您能否获得更具体的异常或导致 PersistenceException 的原因

Can you get more specific exception or cause of getting PersistenceException when calling createEntityManager while using OpenJPA

在使用 OpenJPA 连接到 Derby 数据库时,我遇到了这个 PersistenceException,它表示无法为 Derby EmbeddedDriver 驱动程序获得连接 class,但这并不重要(我知道如何修复它):

77  RegistryManagement  INFO   [JavaFX Application Thread] openjpa.jdbc.JDBC - Using dictionary class "org.apache.openjp
a.jdbc.sql.DerbyDictionary".
<openjpa-3.1.2-r66d2a72 nonfatal general error> org.apache.openjpa.persistence.PersistenceException: There were errors i
nitializing your configuration: <openjpa-3.1.2-r66d2a72 fatal user error> org.apache.openjpa.util.UserException: A conne
ction could not be obtained for driver class "org.apache.derby.jdbc.EmbeddedDriver" and URL "jdbc:derby:db".  You may ha
ve specified an invalid URL.
....

重要的是在那个异常中有这个原因:

....
Caused by: ERROR XJ004: XJ004.C : [0] db
    at 
....

这是 Derby 错误代码之一 (https://db.apache.org/derby/docs/10.5/ref/rrefexcept71493.html)。

这个 PersistenceException 在调用 .createEntityManager() 时被抛出。文字长度是不是很长

我可以通过用 try-catch 包装 .createEntityManager() 来捕获 PersistenceException,但我不知道如何找到有关原因的更多信息,也就是。获取错误代码,因为 PersistenceException 可能由于各种原因抛出。而且我不能用捕获 SQLExceptionUserException 来包装它,因为我的 IDE 说该方法不会抛出这些异常。

我尝试在 PersistenceException 上调用 .getMessage().getCause(),但我收到的文本几乎相同。

当我调用 .getCause() 时 returns RuntimeException 我可以看到这个,德比抛出 SQLException:

....
Caused by: java.sql.SQLException: XJ004.C : [0] db
    at 
....

再次调用 .getCause() returns 无效。

我不想在整个消息 (String) 中搜索某些错误代码的出现,因为这可能会占用大量资源。我认为这个问题可能不是 Derby 特有的,而是在使用其他 sql 数据库时发生的,这也可能引发一些异常。

我的代码:

public class DatabaseManager
{
    private EntityManagerFactory managerFactory;
    private EntityManager manager;

    public DatabaseManager(String persistenceUnitName, Map<String, String> properties)
    {
        managerFactory = Persistence.createEntityManagerFactory(persistenceUnitName, properties);
        try
        {
            manager = managerFactory.createEntityManager();
        }
        catch(PersistenceException e)
        {
            //stuff
        }
    }
....

EntityManagerFactory 是来自 javax.persistence 包的接口:

public interface EntityManagerFactory {

    public EntityManager createEntityManager();
....

调试的时候,在PersistenceExceptionsclass中找到了这个方法,分别是 来自 OpenJPA:

@Override
public RuntimeException translate(RuntimeException re) {
    return PersistenceExceptions.toPersistenceException(re);
}

此方法转换捕获的 RuntimeException,这是由 SQLException 引起的 OpenJPA 的 UserException 问题案例,然后在此基础上创建新的 PersistenceException 和 returns它:

/**
 * Translate the given general exception.
 */
private static Throwable translateGeneralException(OpenJPAException ke) {
   Exception e = new org.apache.openjpa.persistence.PersistenceException
        (ke.getMessage(), getNestedThrowables(ke),
            getFailedObject(ke), ke.isFatal());
    e.setStackTrace(ke.getStackTrace());
    return e;
}

如您所见,根据 OpenJPAException 值(而不是它本身)创建新的 org.apache.openjpa.persistence.PersistenceException 会导致无法检索较低的原因。

OpenJPA 版本 3.1.2