Currently in my hibernate.cfg.xml file, I have to list each individual entity as a mapping class in order for my Hibernate to pick up the Entity or else I get an error like references an unknown entity
.
So I have about 20 of these lines:
<mapping class="my.com.entity.User"></mapping>
<mapping class="my.com.entity.Address"></mapping>
...
Instead of having to put a new line in the XML file each time a new Entity is created, is there a way to tell Hibernate "Hey, just pull in everything from the my.com.entity package as a Entity"?
No. You can't say Hibernate to scan packages for persistent classes even with the last Hibernate 5 version.
Using Spring
The common way to use Spring for that, as @Srini suggested.
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="packagesToScan">
<list>
<value>my.com.entities</value>
<value>my.com.other.entities</value>
</list>
</property>
</bean>
Note that depends of Hibernate version you need to use package: org.springframework.orm.hibernate5
, org.springframework.orm.hibernate4
.
Using fluent-hibernate
If you don't want to use Spring, you can use EntityScanner from fluent-hibernate library (you will not need to have other jars, except the library). Apart this, it has some useful features for Hibernate 5 and Hibernate 4, including entities scanning, a Hibernate 5 implicit naming strategy, a nested transformer and others.
For Hibernate 4 and Hibernate 5:
Configuration configuration = new Configuration();
EntityScanner.scanPackages("my.com.entities", "my.com.other.entities")
.addTo(configuration);
SessionFactory sessionFactory = configuration.buildSessionFactory();
Using a new Hibernate 5 bootstrapping 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();
Using other libraries
If you already use a library that can be used for scanning, for an example Reflections , there is a test project with examples of using various libraries for entity scanning: hibernate-scanners-test .
Two approaches suggested by v.ladynev are good. However, if you don't want to take control over creating Configuration
and Session
by yourself, you can do the following.
In hibernate-cfg.xml
you need to add the custom scanner <property name="hibernate.archive.scanner" value="com.custom.CustomEntityScanner" />
And CustomEntityScanner
implementation goes something like the following. All you need to do is add your custom packages to non-root
urls, everything else is kind of copy from the AbstractScannerImpl.
public class CustomEntityScanner extends AbstractScannerImpl {
private final ArchiveDescriptorFactory archiveDescriptorFactory;
public CustomEntityScanner() {
this(StandardArchiveDescriptorFactory.INSTANCE);
}
protected CustomEntityScanner(ArchiveDescriptorFactory archiveDescriptorFactory) {
this.archiveDescriptorFactory = archiveDescriptorFactory;
}
@Override
public ScanResult scan(ScanEnvironment environment, ScanOptions options, ScanParameters parameters) {
final ScanResultCollector collector = new ScanResultCollector( environment, options, parameters );
//this is specific to your implemenation
List<URL> paths = Lists.newArrayList();
// ClasspathHelper is from Reflections library.
paths.addAll(ClasspathHelper.forPackage("your.custom.package"));
environment.getNonRootUrls().addAll(paths);
inal ArchiveContext context = new ArchiveContextImpl( false, collector );
for ( URL url : environment.getNonRootUrls() ) {
final ArchiveDescriptor descriptor = buildArchiveDescriptor( url, false );
descriptor.visitArchive( context );
}
if ( environment.getRootUrl() != null ) {
final ArchiveContext context = new ArchiveContextImpl( true, collector );
final ArchiveDescriptor descriptor = buildArchiveDescriptor( environment.getRootUrl(), true );
descriptor.visitArchive( context );
}
return collector.toScanResult();
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.