3

私は、Hibernate をコンテナーの外部で使用する簡単な例を開発しています。私は Maven を使用しているため、JBoss リポジトリを構成し ( https://community.jboss.org/wiki/MavenGettingStarted-Usersを参照)、プロジェクトの POM に次の依存関係を追加しました。

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>4.2.0.CR1</version>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.3.170</version>
</dependency>

次に、次のように H2 データベースを使用するように Hibernate を構成しました (ファイル hibernate.cfg.xml):

<?xml version='1.0' encoding='utf-8'?>
<hibernate-configuration xmlns="http://www.hibernate.org/xsd/hibernate-configuration">
    <session-factory>
        <property name="hibernate.connection.driver_class">org.h2.Driver</property>
        <property name="hibernate.connection.url">jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE</property>
        <property name="hibernate.connection.username">sa</property>
        <property name="hibernate.connection.password"></property>

        <property name="hibernate.connection.pool_size">1</property>
        <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
        <property name="hibernate.cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>
    </session-factory>
</hibernate-configuration>

最後に、以下のように単純な連絡先クラスの POJO を作成しました。

@Entity
public class Contact {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Basic
    private String name;

    @Basic
    private String email;

    /* Getters and setters omitted for brevity. */
}

最後に、セッション ファクトリであるセッションを取得し、最後にエンティティを永続化するクラスを作成しました。コードは次のとおりです。

    ServiceRegistry registry = new ServiceRegistryBuilder().configure().buildServiceRegistry();
    MetadataSources sources = new MetadataSources(registry);
    sources.addAnnotatedClass(Contact.class);
    Metadata metadata = sources.buildMetadata();
    sessionFactory = metadata.buildSessionFactory();

    Contact contact = new Contact();
    /* Set some attributes. */

    Session session = sessionFactory.openSession();
    session.save(contact);
    session.close();

このコードを実行すると、次のようになります。

Exception in thread "main" java.lang.NoClassDefFoundError: org/jboss/jandex/Indexer
    at org.hibernate.metamodel.source.annotations.AnnotationMetadataSourceProcessorImpl.prepare(AnnotationMetadataSourceProcessorImpl.java:78)
    at org.hibernate.metamodel.source.internal.MetadataImpl.prepare(MetadataImpl.java:177)
    at org.hibernate.metamodel.source.internal.MetadataImpl.<init>(MetadataImpl.java:162)
    at org.hibernate.metamodel.source.internal.MetadataBuilderImpl.buildMetadata(MetadataBuilderImpl.java:83)
    at org.hibernate.metamodel.MetadataSources.buildMetadata(MetadataSources.java:112)

プロジェクトに追加した依存関係の POM を調べると、org.hibernate/hibernate-core依存関係があることがわかりますorg.jboss/jandex 1.0.3.Final。その依存関係を満たすと、NoClassDefFoundError: com/fasterxml/classmate/TypeResolver. Hibernate の POM に戻ると、依存していcom.fasterxml/classmate 0.5.4ます。私のプロジェクトでもその依存関係を満たすことで、最終的にNoClassDefFoundErrors なしでコードを実行できるようになりました。

Hibernate の POM では、jandex と classmate の両方がtest依存関係として定義されているため、Maven の推移的な依存関係解決機能によってプロジェクトに自動的に追加されません。しかし、なぜ単純なコードを実行するときに必要なのですか? 私は何を間違っていますか?

ご指摘ありがとうございます。- ビトール

4

1 に答える 1

7

JandexとClassmateは、Hibernateの主な機能には必要ありません。ただし、メタデータの生成には必要です(参照)。メタデータ生成を使用しない人々のために物事を壊さないために、彼らは依存関係をテスト依存関係として追加しました。メタデータ生成を使用している場合は、それらの依存関係を取得する必要があります。

于 2013-03-02T03:32:29.457 に答える