2009-09-11 23 views
36

Tôi đang sử dụng Chú thích ngủ đông.Gói bản đồ Hibernate

Trong tất cả các lớp mô hình của tôi, tôi chú thích như thế này:

@Entity 
@Table 
public class SomeModelClass { 
// 
} 

hibernate.cfg.xml tôi là

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

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

Đối với mỗi lớp tôi thêm vào com.fooPackage tôi có thêm một dòng trong tệp hibernate.cfg.xml như sau:

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

Có cách nào tôi có thể thêm lớp mô hình mới nhưng không cần thêm dòng này vào hibernate.cfg.xml?

+16

Điều đáng chú ý là mục ' skaffman

Trả lời

18

Hết hộp - không. Tuy nhiên, bạn có thể viết mã của riêng mình để phát hiện/đăng ký các lớp được chú thích của mình. Nếu bạn đang sử dụng Spring, bạn có thể mở rộng AnnotationSessionFactoryBean và làm điều gì đó như:

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

Nếu bạn không sử dụng Spring (và bạn nên :-)) bạn có thể viết mã riêng của bạn để phát hiện các lớp học phù hợp và đăng ký chúng với AnnotationConfiguration của bạn thông qua phương thức addAnnotatedClass().

Ngẫu nhiên, không cần thiết phải ánh xạ các gói trừ khi bạn đã thực sự khai báo một thứ gì đó ở cấp gói.

+0

Wow Chss, Đây là lần đầu tiên tôi thấy ClassPathScanningCandidateComponentProvider. Rất tốt. Đã xác nhận –

11

Tôi chỉ gặp vấn đề này và tìm ra giải pháp cho giải pháp này. Tích hợp của tôi chưa ra, sẽ cập nhật sau này.

Từ Javadoc, đặc biệt là packagesToScan phần:

org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean

Subclass của LocalSessionFactoryBean chuẩn Spring cho Hibernate, hỗ trợ JDK 1.5 + chú thích siêu dữ liệu cho ánh xạ.

Lưu ý: Lớp này yêu cầu Hibernate 3.2 trở lên, với Java API Persistence và phần bổ trợ Chú thích Hibernate hiện tại.

Ví dụ cho một định nghĩa AnnotationSessionFactoryBean đậu:

<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> 

Hoặc khi sử dụng chức năng quét classpath cho dò các lớp thực thể:

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

Từ: 1.2.2
Tác giả: Juergen Hoeller

+0

, hoạt động như mong đợi. –

+0

Điều này làm việc cho tôi quá .. Cảm ơn câu trả lời của bạn ... –

10

Số lượng necromancy chủ đề tại đây ...

Nó vẫn không giống như có một cách tốt để làm những gì bạn muốn. Nếu bạn không muốn sử dụng Spring, đây là một phương pháp tương tự sử dụng 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); 

Các phương pháp tương tự có lẽ là khả thi cho các thư viện phản ánh Java khác.

+0

Hãy nhớ rằng, cách này cấu hình không hoạt động cho Hibernate 5. Nó nên được thay đổi. –

1

Nếu bạn không muốn sử dụng spring hoặc bất kỳ thư viện nào khác, bạn có thể đạt được điều đó như thế này. Cùng cách tiếp cận như luke's nhưng không Reflections thư viện

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

Tôi đã thực hiện một số cuộc điều tra của phương pháp quét lớp, sử dụng câu trả lời từ StackOverflow. Vì vậy, tôi thu thập tất cả lại với nhau, sử dụng một thực thể Hibernate quét như một thử nghiệm, trong một dự án thử nghiệm: hibernate-scanners-test.

Sử dụng thành thạo-ngủ đông

Nếu bạn đang tìm kiếm một phương pháp quét nhanh chóng mà không phụ thuộc bổ sung, bạn có thể thử fluent-hibernate thư viện (bạn sẽ không cần phải có lọ khác, ngoại trừ thư viện). Ngoài ra, nó có một số tính năng hữu ích cho Hibernate 5 và Hibernate 4, bao gồm các thực thể quét, một chiến lược đặt tên ẩn danh Hibernate 5, một biến áp lồng nhau và những người khác.

Chỉ cần tải thư viện từ trang dự án: fluent-hibernate và sử dụng :

Đối với Hibernate 4 và Hibernate 5:

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

Sử dụng một API Hibernate 5 bootstrapping mới:

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"); 
Các vấn đề liên quan