2009-09-11 13 views
36

私はHibernate注釈を使用しています。私はこのような注釈を付けるすべての私のモデルクラスでHibernateマッピングパッケージ

@Entity 
@Table 
public class SomeModelClass { 
// 
} 

私のhibernate.cfg.xmlのは、私は私が追加する必要がcom.fooPackageに追加したすべてのクラスのために

<hibernate-configuration> 
    <session-factory> 
     <!-- some properties --> 

     <mapping package="com.fooPackage" /> 
     <mapping class="com.fooPackage.SomeModelClass" /> 
    </session-factory> 
</hibernate-configuration> 

ですこのようなhibernate.cfg.xmlの中の行:

<mapping class="com.fooPackage.AnotherModelClass" /> 

は、私は新しいモデルクラスを追加することができますが、する必要はありません方法はありますこの行をhibernate.cfg.xmlに追加しますか?

+16

答えて

18

すぐに利用できます。ただし、注釈付きクラスを検出/登録する独自のコードを記述することはできます。あなたが春を使用している場合は、AnnotationSessionFactoryBeanを拡張することができ、ような何か:あなたは適切なクラスを検出するための独自のコードを書くことができます(あなたが:-)する必要があります)スプリングを使用していない場合は

@Override 
protected SessionFactory buildSessionFactory() throws Exception { 
    ArrayList<Class> classes = new ArrayList<Class>(); 

    // the following will detect all classes that are annotated as @Entity 
    ClassPathScanningCandidateComponentProvider scanner = 
    new ClassPathScanningCandidateComponentProvider(false); 
    scanner.addIncludeFilter(new AnnotationTypeFilter(Entity.class)); 

    // only register classes within "com.fooPackage" package 
    for (BeanDefinition bd : scanner.findCandidateComponents("com.fooPackage")) { 
    String name = bd.getBeanClassName(); 
    try { 
     classes.add(Class.forName(name)); 
    } catch (Exception E) { 
     // TODO: handle exception - couldn't load class in question 
    } 
    } // for 

    // register detected classes with AnnotationSessionFactoryBean 
    setAnnotatedClasses(classes.toArray(new Class[classes.size()])); 
    return super.buildSessionFactory(); 
} 

をし、 にaddAnnotatedClass()メソッドで登録してください。

実際にパッケージレベルで何かを宣言していない限り、パッケージをマップする必要はありません。

+0

Wow Chss、ClassPathScanningCandidateComponentProviderを初めて見ました。とても良い。 –

11

私はちょうどこの問題に遭遇し、そこにはこれのための箱入りの解決策があるようです。私の統合はまだ終わっていません。後でこれを更新します。 Javadocのから

、特にpackagesToScan一部:休止状態のためのSpringの標準LocalSessionFactoryBeanの

org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean

サブクラス、 は、マッピング用のJDK 1.5以降注釈メタデータをサポートしています。

注:このクラスには、Java Persistence APIとHibernate Annotationsアドオンが存在するHibernate 3.2以降が必要です。

AnnotationSessionFactoryBeanビーン定義の例:

<bean id="sessionFactory" 
     class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="packagesToScan" value="test.package"/> 
</bean> 

以来:1.2.2
者:ユルゲンHoeller

<bean id="sessionFactory" 
     class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="annotatedClasses"> 
    <list> 
     <value>test.package.Foo</value> 
     <value>test.package.Bar</value> 
    </list> 
    </property> 
</bean> 

またはエンティティ・クラスの自動検出のためのクラスパスのスキャンを使用する場合

+0

が確認されました。期待どおりに動作しています。 –

+0

これも私のために働いた..あなたの答えをありがとう... –

10

ここにスレッドネクロのビット...

あなたが望むことをする良い方法があるようにはまだ見えません。あなたが春を使用したくない場合は、ここでReflectionsを使用して同様の方法があります:

// Create your SessionFactory with mappings for every `Entity` in a specific package 
Configuration configuration = new Configuration(); 
configuration.configure("your_hibernate.cfg.xml"); 

Reflections reflections = new Reflections("your_package"); 

Set<Class<?>> classes = reflections.getTypesAnnotatedWith(javax.persistence.Entity.class); 

for(Class<?> clazz : classes) 
{ 
    configuration.addAnnotatedClass(clazz); 
} 

ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build(); 
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry); 

同じアプローチは、おそらく他のJavaリフレクションライブラリの実行可能です。

+0

この設定方法はHibernate 5では機能しません。変更する必要があります。 –

1

springまたは他のライブラリを使用しない場合は、このようにすることができます。同じアプローチluke'sとしてではなく、私はStackOverflowのからの回答を使用して、クラスのスキャニングアプローチのいくつかの調査を行っている

import org.hibernate.SessionFactory; 
import org.hibernate.boot.registry.StandardServiceRegistryBuilder; 
import org.hibernate.cfg.Configuration; 
import org.hibernate.service.ServiceRegistry; 

import javax.persistence.Entity; 
import javax.tools.FileObject; 
import javax.tools.JavaFileObject; 
import javax.tools.StandardJavaFileManager; 
import javax.tools.StandardLocation; 
import javax.tools.ToolProvider; 
import java.io.File; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.Collection; 
import java.util.Collections; 
import java.util.regex.Pattern; 
import java.util.stream.Collectors; 
import java.util.stream.StreamSupport; 

public class SessionFactoryWrapper { 

    private final SessionFactory sessionFactory; 

    public SessionFactoryWrapper(final String...packagesToScan) { 
     this.sessionFactory = this.createSessionFactory(packagesToScan); 
    } 

    private SessionFactory createSessionFactory(final String[] packagesToScan) { 
     final Configuration configuration = new Configuration(); 
     configuration.configure(); // Reads hibernate.cfg.xml from classpath 

     for (String packageToScan : packagesToScan) { 
      this.getEntityClasses(packageToScan).stream().forEach(configuration::addAnnotatedClass); 
     } 

     final ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build(); 
     return configuration.buildSessionFactory(serviceRegistry); 
    } 

    private Collection<Class> getEntityClasses(final String pack) { 
     final StandardJavaFileManager fileManager = ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null); 
     try { 
      return StreamSupport.stream(fileManager.list(StandardLocation.CLASS_PATH, pack, Collections.singleton(JavaFileObject.Kind.CLASS), false).spliterator(), false) 
        .map(FileObject::getName) 
        .map(name -> { 
         try { 
          final String[] split = name 
            .replace(".class", "") 
            .replace(")", "") 
            .split(Pattern.quote(File.separator)); 

          final String fullClassName = pack + "." + split[split.length - 1]; 
          return Class.forName(fullClassName); 
         } catch (ClassNotFoundException e) { 
          throw new RuntimeException(e); 
         } 

        }) 
        .filter(aClass -> aClass.isAnnotationPresent(Entity.class)) 
        .collect(Collectors.toCollection(ArrayList::new)); 
     } catch (IOException e) { 
      throw new RuntimeException(e); 
     } 
    } 

    public SessionFactory getSessionFactory() { 
     return sessionFactory; 
    } 
} 
0

Reflectionsライブラリなし。だから、1つのテストプロジェクトでHibernateエンティティをテストとしてスキャンして、すべて一緒に集めます:hibernate-scanners-test。あなたは追加の依存関係なしに迅速にスキャンアプローチを探しているなら

流暢、休止状態

を使用すると、あなたは(あなたがライブラリを除いて、他のjarファイルを持っている必要はありません)fluent-hibernateライブラリを試すことができます。 これ以外にも、Hibernate 5とHibernate 4には、エンティティスキャン、Hibernate 5暗黙的ネーミング戦略、ネストされたトランスフォーマーなどの便利な機能がいくつかあります。

ただ、プロジェクトページからライブラリをダウンロード:fluent-hibernateとを使用します。

休止状態4の場合と5を休止:新しいHibernateは5ブートストラップAPI使用

Configuration configuration = new Configuration(); 
EntityScanner.scanPackages("my.com.entities", "my.com.other.entities") 
    .addTo(configuration); 
SessionFactory sessionFactory = configuration.buildSessionFactory(); 

List<Class<?>> classes = EntityScanner 
     .scanPackages("my.com.entities", "my.com.other.entities").result(); 

MetadataSources metadataSources = new MetadataSources(); 
for (Class<?> annotatedClass : classes) { 
    metadataSources.addAnnotatedClass(annotatedClass); 
} 

SessionFactory sessionFactory = metadataSources.buildMetadata() 
    .buildSessionFactory(); 
-1
1. XML 
<mapping class="com.concretepage.Person"/> 

2. Class 
    Configuration configuration = new Configuration().configure().addAnnotatedClass(Person.class); 

      //Configure all the classes. 

      Set<Class> entityClasses = new HashSet<>(Arrays.asList(Person.class,PersonDetails.class)); 
//Iterate all the Classes. 
      for (Class cls : entityClasses) { 
       configuration.addAnnotatedClass(cls); 
      } 
3. Add package   
//Or you can add package 
      configuration.addPackage("com.domain.entity");