预先配置的netbeans项目与NoSuchMethodError hibernate和spring冲突

时间:2013-02-11 04:16:30

标签: java spring hibernate netbeans jdbc

所以我试图让我的Java应用程序通过 Microsoft JDBC Driver 4.0 for SQL Server连接到SQL Server 2012,而且一切似乎进展顺利但是hibernate只是不断回到NullExceptions并且不会执行try/catch内的任何事情(因此NullException),我完全不知道为什么。以下是来自运行hibernate的netbeans控制台(e.getMessage())的pastebin(出于此问题的目的,我使用的是名为prime_table的示例表。)

在pastebin日志中,您会注意到......

  

2013年2月11日下午5:21:04 org.hibernate.cfg.Configuration doConfigure   信息:已配置的SessionFactory:null

有关为何发生这种情况的任何想法? (我不确定,但它可能与整个堆栈跟踪有关。)

其他日志(在JSP构建期间)

所有日志将在2013年3月中旬/后期之前提供

资源,我一直在阅读

预先配置的Netbeans项目设置commandline: tree /f

netbeans http://iforce.co.nz/i/llroxgez.s5s.png

Hibernate.cfg.xml (根据Hari的建议添加"hibernate.cache.provider_class"

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
    <property name="hibernate.connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
    <property name="hibernate.connection.url">jdbc:sqlserver://Michael-PC:1433;databaseName=PrimeDB</property>
    <property name="hibernate.connection.username">sa</property>
    <property name="hibernate.connection.password">online12</property>
    <property name="hibernate.connection.pool_size">10</property>
    <property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
    <property name="hibernate.show_sql">true</property>
    <property name="hibernate.hbm2ddl.auto">update</property>
    <!-- Data Mappings -->
    <mapping resource="prime.hbm.xml"/>
  </session-factory>
</hibernate-configuration>

public class Prime {

    private long prime;

    public void setPrime(long nPrime){
        this.prime = nPrime;
    }

    public long getPrime(){
        return this.prime;
    }

}

prime.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="nz.co.xyleap.db.Prime" table="prime_table">
    <id name="prime" type="long" column="prime" />
  </class>
</hibernate-mapping>

Prime Table

CREATE TABLE prime_table (
    [prime] bigint PRIMARY KEY NOT NULL,
)

会话功能或FirstExample.java

public class FirstExample {

    public static void main(String[] args) {
        FirstExample ex = new FirstExample();
        ex.session();
    }

    public void session() {
        Session session = null;
        try {
            // This step will read hibernate.cfg.xml and prepare hibernate for use
            SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
            session = sessionFactory.openSession();
            session.beginTransaction();
            //Create new instance of Contact and set values in it by reading them from form object
            System.out.println("inserting record 13");
            Prime p = new Prime();
            p.setPrime(13);
            session.save(p);
            System.out.println("Done");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            // Actual contact insertion will happen at this step
            session.flush();
            session.close();
        }
    }

}

据我所知,一切都应该是正确的,我应该能够将Java Hibernate中的记录插入到我的SQL数据库中。但由于某种原因,我不能: - /

更新:Hibernate本身运行良好。但是与Spring一起,会发生这些错误。 (评论中的更多信息)。

2 个答案:

答案 0 :(得分:5)

看起来你错过了Hibernate在运行时需要的库。我看到了与您的代码(MySQL 5,MySQL JDBC驱动程序,Mac OS)相同的行为,直到我更改了行:

catch (Exception e) {
      System.out.println(e.getMessage());
}

要:

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

然后我开始看到有关Hibernate正在寻找但未包含在我的CLASSPATH中的库的一整套NoClassDefFoundErrorClassNotFoundError消息。我怀疑你错过了一个Hibernate需要的库,并且因为你正在捕获Exception而不是Throwable - 它捕获Error - 你没有看到错误消息。参见:

Why catch Exceptions in Java, when you can catch Throwables?

如果你赶上Throwable,你会很快看到你缺少的库和类:我的猜测是你可能缺少EHCache(Hibernate似乎用作二级缓存)默认情况下),CGLIB / ASM或Java Transaction API。如果您缺少EHCache并希望hibernate使用自己的内存中Hashtable缓存而不是EHCache,请将下面的行添加到hibernate.cfg.xml

<property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>

更新,根据回答的评论:

我不使用NetBeans,因此我没有遇到这个问题,但它看起来相当普遍。参见:

Error : java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.<init>(I)V

http://www.hildeberto.com/2008/05/hibernate-and-jersey-conflict-on.html(报告Netbeans中Hibernate和Jersey的类似问题)

https://hibernate.onjira.com/browse/HHH-2222(Hibernate bug报告提到了这个问题)

http://netbeans.org/bugzilla/show_bug.cgi?id=145589(使用旧版cglib捆绑Hibernate的Netbeans错误报告)。

上面链接的StackOverflow帖子有很多细节。总结一下:

  • Hibernate 3.2使用CGLib 2.1.3进行运行时代码生成,以提高性能并生成一对一和一对多映射的代理。

  • CGLib是ASM的高级包装器,ASM是一个字节码操作库。 CGLib 2.1.3要求ASM 1.5.3,二进制不兼容与ASM 2.2。 ASM 2.2又是Spring版本的依赖项&lt; 2.5

  • 为了解决Hibernate和Spring之间的这些问题,Spring 2.5将自己的asm版本与spring包名称捆绑在一起;更高版本的Hibernate使用CGLIB 2.2,它还将自己的ASM版本与自定义包名称捆绑在一起。最新版本的Hibernate完全取消了CGLIB,而是使用Javassist,但NetBeans仍捆绑了Hibernate 3.2.5。

您有几个选择,然后:

  • 使用CGLIB 2.2更新Netbeans中的Hibernate库包

  • 告诉Hibernate使用Javassist进行运行时代码生成。将此行添加到hibernate.properties,或使用-D将其指定为系统属性(显然,您无法在hibernate.cfg.xml中指定此属性):

    hibernate.bytecode.provider=javassist

祝你好运,这是一个非常有趣的问题!

答案 1 :(得分:-1)

在session.flush();因为session是null并且try-block中的某些东西抛出了一个异常,可能是像nullpointer之类的运行时异常。会话为空的事实将导致另一个nullptr,它将隐藏原始的。所以我建议你做到这一点

if(session!=null)
{
    session.flush();
    session.close();
}

然后运行它以查看实际问题是什么。

我还建议您替换“System.out.println(e.getMessage());”与至少e.printStackTrace();或者最好是适当的记录