使Hibernate Initializer免于崩溃程序

时间:2010-05-11 19:56:52

标签: java hibernate exception exception-handling

我有一个使用基本Hibernate会话工厂的Java程序。我遇到了hibernate hbm.xml映射文件的问题,即使我在try catch中调用了getSessionFactory(),它也崩溃了我的程序

                try
                {
                    session = SessionFactoryUtil.getSessionFactory().openStatelessSession();    
                    session.beginTransaction();
                    rh = getRunHistoryEntry(session);
                    if(rh == null)
                    {
                        throw new Exception("No run history information found in the database for run id " + runId_ + "!");
                    }
                }
                catch(Exception ex)
                {
                    logger.error("Error initializing hibernate");
                }

它仍然设法突破这个try / catch并使主线程崩溃。我如何防止它这样做?主要问题是我有一堆清理命令,需要在主线程关闭之前运行,并且需要能够保证即使在失败之后它仍然可以清理并且稍微优雅地下降。会话工厂看起来像这样:

public class SessionFactoryUtil {
    private static final SessionFactory sessionFactory;  

    static {  
        try 
        {  
            // Create the SessionFactory from hibernate.cfg.xml  
            sessionFactory = new Configuration().configure().buildSessionFactory();
        } 
        catch (Throwable ex) 
        {  
            // Make sure you log the exception, as it might be swallowed  
            System.err.println("Initial SessionFactory creation failed." + ex);  
            throw new ExceptionInInitializerError(ex);  
        }  
    }  

    public static SessionFactory getSessionFactory() 
    {   try
        {
            return sessionFactory;
        }
        catch(Exception ex)
        {
            return null;
        }
    }  
}

抛出的错误如下,我已修复它,但我想防止任何hibernate初始化错误停止主线程。

Initial SessionFactory creation failed.org.hibernate.InvalidMappingException: Could not parse mapping document from resource hibernate/TmdIndataLine.hbm.xml
Exception in thread "main" java.lang.ExceptionInInitializerError
    at com.ryanco.db.SessionFactoryUtil.<clinit>(SessionFactoryUtil.java:19)
    at com.ryanco.rta.RtaMain.main(RtaMain.java:148)
Caused by: org.hibernate.InvalidMappingException: Could not parse mapping document from resource hibernate/TmdIndataLine.hbm.xml
    at org.hibernate.cfg.Configuration.addResource(Configuration.java:616)
    at org.hibernate.cfg.Configuration.parseMappingElement(Configuration.java:1635)
    at org.hibernate.cfg.Configuration.parseSessionFactory(Configuration.java:1603)
    at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1582)
    at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1556)
    at org.hibernate.cfg.Configuration.configure(Configuration.java:1476)
    at org.hibernate.cfg.Configuration.configure(Configuration.java:1462)
    at com.ryanco.db.SessionFactoryUtil.<clinit>(SessionFactoryUtil.java:13)
    ... 1 more
Caused by: org.hibernate.InvalidMappingException: Could not parse mapping document from input stream
    at org.hibernate.cfg.Configuration.addInputStream(Configuration.java:555)
    at org.hibernate.cfg.Configuration.addResource(Configuration.java:613)
    ... 8 more
Caused by: org.dom4j.DocumentException: Error on line 114 of document  : The element type "class" must be terminated by the matching end-tag "</class>". Nested exception: The element type "class" must be terminated by the matching end-tag "</class>".
    at org.dom4j.io.SAXReader.read(SAXReader.java:482)
    at org.hibernate.cfg.Configuration.addInputStream(Configuration.java:546)
    ... 9 more

3 个答案:

答案 0 :(得分:1)

SessionFactoryUtil中的静态初始化程序对所有Throwable实例都有一个try / catch,但是你的主try / catch块只捕获异常。我会改变它以捕捉Throwables,看看是否能解决问题。

答案 1 :(得分:0)

那么,根据您编写的应用程序类型,静态初始化程序执行任何到达JVM外部的操作通常都是一个坏主意。

问题:如果我正确地读了你的代码,你首先会在Throwable的静态初始化器中捕获所有SessionFactoryUtil,向标准错误写一条错误消息然后抛出一个新的ExceptionInInitializerError自己,将cat Throwable包裹在其中。

在加载类之后,首先调用IIRC静态初始化器。堆栈跟踪告诉我们这可能来自类RtaMain中的main方法,因为SessionFactoryUtil.getSessionFactory()似乎是从那里调用的,这会触发类加载。

要捕获此错误,您需要在类getSessionFactory()的main方法中调用RtaUtil周围的try / catch,捕获Throwable,或至少在静态初始化程序中抛出的特定throwable你自己,ExceptionInInitializerError

HTH

答案 2 :(得分:0)

  

它仍然设法突破这个try / catch并使主线程崩溃。

如前所述,main方法中的这个bloc不会捕获静态初始值设定项中抛出的ExceptionInInitializerError

catch(Exception ex) {
    logger.error("Error initializing hibernate")
}

如果你想同时抓住ExceptionError,你应该catch (Throwable t)(顺便说一句,我注意到你说你改变了但是我想知道你改变了什么确切地说,你得到的错误。

但说实话,如果SessionFactory未能初始化,我想知道你在main方法中要做什么,实际上通常的做法是让程序失败。情况下。

最后,这部分的try/catch似乎完全没用:

public static SessionFactory getSessionFactory() {
    try {
        return sessionFactory;
    } catch(Exception ex) {
        return null;
    }
} 

您可以安全地将其删除。