休眠映射包
我正在使用Hibernate注释。休眠映射包
在我所有的模型类我注释是这样的:
@Entity
@Table
public class SomeModelClass {
//
}
我的hibernate.cfg.xml是
<hibernate-configuration>
<session-factory>
<!-- some properties -->
<mapping package="com.fooPackage" />
<mapping class="com.fooPackage.SomeModelClass" />
</session-factory>
</hibernate-configuration>
对于每一个I类添加到com.fooPackage我要补充一个行像这样的hibernate.cfg.xml:
<mapping class="com.fooPackage.AnotherModelClass" />
有没有一种方法,我可以添加新的模型类,但并不需要将此行添加到hibernate.cfg.xml?
开箱即用 - 无。但是,您可以编写自己的代码来检测/注册您的注释类。如果你使用Spring,你可以扩展AnnotationSessionFactoryBean
和这样做:如果你不使用Spring
@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()
方法注册您的AnnotationConfiguration
。
顺便说一下,除非您已经在包级别上实际声明了某些内容,否则不需要映射包。
哇Chss,这是我第一次见到ClassPathScanningCandidateComponentProvider。很好。 – 2009-09-12 14:58:33
我刚刚遇到了这个问题,并且发现那里似乎有一个开箱即用的解决方案。我的整合还没有结束,稍后会进行更新。
从的Javadoc,尤其是packagesToScan
部分:
org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean
Spring对Hibernate的, 标准的LocalSessionFactoryBean支持JDK 1.5 +注解元数据映射的子类。
注意:此类需要Hibernate 3.2或更高版本,并且存在Java Persistence API和Hibernate Annotations插件。
实施例用于
AnnotationSessionFactoryBean
bean定义:<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>
或使用类路径扫描实体类的自动检测时:
<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
证实,它按预期工作。 – 2011-08-09 08:27:18
这里的线程死灵位......
它仍然不像是有一种很好的方式来做你想做的事情。如果你不想使用Spring,这里是一个使用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反射库。
请记住,这种配置方式不适用于Hibernate 5。应该改变。 – 2016-05-26 07:19:58
如果你不想使用spring
或任何其他库,你可以实现这样的。相同的方法luke's但没有Reflections
库
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;
}
}
我做的类扫描方法的一些调查,使用的答案从*上。所以我把它们集中在一起,在一个测试项目中使用Hibernate实体扫描作为测试:hibernate-scanners-test。
使用流畅,休眠
如果你没有额外的依赖关系寻找一种快速扫描的方法,你可以尝试fluent-hibernate库(你不需要有其他的罐子,图书馆除外)。 除此之外,它还具有Hibernate 5和Hibernate 4的一些有用功能,包括实体扫描,Hibernate 5隐式命名策略,嵌套变换器等。
刚刚从项目页面下载库:fluent-hibernate和使用:
对于休眠4和Hibernate 5:
Configuration configuration = new Configuration();
EntityScanner.scanPackages("my.com.entities", "my.com.other.entities")
.addTo(configuration);
SessionFactory sessionFactory = configuration.buildSessionFactory();
使用一个新的Hibernate 5引导API:
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. 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");
值得注意的是,' '条目用于配置包本身定义的元数据,而不是包*中的类*。 –
skaffman
2009-09-11 21:12:08