2009-09-11 23 views
36

Hazırda Bekletme Ek Açıklamaları kullanıyorum. Tüm modeli sınıflarında Hazırda Beklet Eşleme Paketi

böyle açıklama:

@Entity 
@Table 
public class SomeModelClass { 
// 
} 

Benim hibernate.cfg.xml ben com.fooPackage eklediğiniz her sınıf için

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

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

olan bir eklemek zorunda böyle hibernate.cfg.xml satır:

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

bir yol Ben yeni model sınıfları ekleyebilir ancak gerekmez mi var Bu satırı hibernate.cfg.xml dosyasına ekleyin

+16

cevap

18

Kutudan - hayır. Bununla birlikte, açıklamalı sınıflarınızı tespit etmek/kaydetmek için kendi kodunuzu yazabilirsiniz. Eğer Bahar kullanarak ediyorsanız, AnnotationSessionFactoryBean uzatmak ve benzeri bir şey yapabilirsiniz: Uygun sınıflar tespit etmek için kendi kodunuzu yazabilirsiniz

@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(); 
} 

Eğer bahar kullanmıyorsanız (ve :-) olmalıdır) ve addAnnotatedClass() yöntemi ile AnnotationConfiguration ile kayıt olunuz.

Ayrıca, paket düzeyinde bir şey bildirmediyseniz, paketleri eşleştirmek gerekmez.

+0

Wow Chss, ClassPathScanningCandidateComponentProvider'ı ilk gördüğüm zamandı. Çok iyi. –

11

Sadece bu sorunla karşılaşıyorum ve bunun için kutudan çıkmış bir çözümün olduğunu görüyorum. Entegrasyonum henüz bitmedi, bunu daha sonra günceller. Javadoc itibaren

, özellikle packagesToScan kısmı: eşleştirmeleri için JDK 1.5+ açıklama meta destekleyen hazırda, için Spring'in standart LocalSessionFactoryBean ait

org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean

alt sınıf.

Not: Bu sınıf, Java Kalıcılık API'sı ve Hazırda Bekletme Ek Açıklamaları eklentisi ile birlikte Hazırda Bekleme 3.2 veya daha yenisini gerektirir.

bir AnnotationSessionFactoryBean fasulye tanımı için örnek:

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

beri: 1.2.2
Yazar: Juergen 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> 

Veya varlık sınıflarının autodetection için sınıf yolu tarama kullanırken

+0

onaylandı, beklendiği gibi çalışıyor. –

+0

Bu benim için de işe yaradı .. Cevabınız için teşekkürler ... –

10

İplik necromancy burada ...

Hala istediğiniz şeyi yapmak için iyi bir yol var gibi görünmüyor. Eğer bahar kullanmak istemiyorsanız, buraya Reflections kullanarak benzer bir yöntem var:

// 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); 

aynı yaklaşım muhtemelen diğer Java yansıma kütüphaneleri için geçerli olduğunu.

+0

Yapılandırmanın bu şekilde Hazırda Bekletme 5 için çalışmadığını unutmayın. değiştirilmeli. –

1

spring veya başka bir kitaplık kullanmak istemiyorsanız, bunun gibi bir performans elde edebilirsiniz. Aynı yaklaşım luke's olarak ama StackOverflow'daki gelen yanıtları kullanarak, sınıf tarama yaklaşımlarının bazı araştırmalar yaptık

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 kütüphanede olmadan. Bu nedenle, bir test projesinde, bir test olarak taranan Hazırda Bekletme öğelerini kullanarak hepsini bir araya getiriyorum: hibernate-scanners-test. Ek bağımlılıklar olmadan hızlı bir tarama yaklaşımı arıyorsanız kullanma

(kitaplıkta hariç diğer kavanoz olması gerekmez) Eğer fluent-hibernate kitaplığını deneyebilirsiniz,

akıcı-hazırda bekleme. Bunun dışında, varlıklar taraması, Hazırda Bekleme 5 örtük bir adlandırma stratejisi, iç içe geçmiş bir transformatör ve diğerleri de dahil olmak üzere Hazırda Beklet 5 ve Hazırda Beklet 4 için bazı yararlı özelliklere sahiptir.

Sadece proje sayfasından kütüphane indirmek: fluent-hibernate ve kullanımı :

hazırda 4 için ve 5 Hazırda:

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

yeni hazırda 5 önyükleme API kullanarak:

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"); 
İlgili konular