简体   繁体   中英

Hibernate config not list all Entities in XML

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM