Description
Joris Kuipers opened SPR-10910 and commented
I'm using LocalContainerEntityManagerFactoryBean#setPackagesToScan
without a persistence.xml
in combination with Hibernate. This works great for annotated entities, but fails to pick up annotated packages. Case in point: I'm using an @FilterDef
that I don't want to have to repeat on multiple entities, so I've placed it on a package.
This works with a persistence.xml
as Hibernate does some additional work when building the PersistenceUnitInfo
then, but I would like to remain persistence.xml
-less if possible.
From what I can see, the JPA PersistenceUnitInfo
(which Spring creates for me in this case) simply doesn't provide support to pass in annotated packages. However, there is (at least for Hibernate) a workaround: from inside the HibernatePersistenceProvider
you can call Ejb3Configuration#addPackage
to have Hibernate pick up the annotated packages. So, for now I'm subclassing the HibernatePersistenceProvider
and override createContainerEntityManagerFactory(PersistenceUnitInfo, Map)
like this:
public class SmartHibernatePersistence extends HibernatePersistence {
private String[] annotatedPackages = new String[0];
/**
* Overridden to allow specifying annotated packages. Without this, when you use Spring's
* {@link LocalContainerEntityManagerFactoryBean#setPackagesToScan(String...)} package-level
* annotations are not picked up.
*/
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map properties) {
Ejb3Configuration cfg = new Ejb3Configuration();
for (String annotatedPackage: annotatedPackages) {
cfg.addPackage(annotatedPackage);
}
Ejb3Configuration configured = cfg.configure( info, properties );
return configured != null ? configured.buildEntityManagerFactory() : null;
}
public void setAnnotatedPackages(String... annotatedPackages) {
this.annotatedPackages = annotatedPackages;
}
}
and then call LCEMFB#setPersistenceProvider
with a configured instance of this class.
That does however require me to specify all my annotated packages (there is no recursive scanning here).
It would be way cooler if Spring would recursively scan for annotated packages when using LCEMFB#setPackagesToScan
and would then pass them on to a Spring-provided extension of the native JPA provider's PersistenceProvider
implementation that knows how to register these annotated packages: for example, by having it's own subtype of the PersistenceProvider
interface that is 'package aware' that is supported in addition to the regular PersistenceProvider
, with implementations for the common JPA providers.
So, basically, that's my feature request ;)
I haven't checked how this works for other JPA providers, but I assume they should provide similar ways to deal with annotated packages when building up their own EntityManagerFactoryBean
from their configuration.
Issue Links:
- In AnnotationSessionFactoryBean, be able to specify annotatedPackages and packagesToScan in one property [SPR-10288] #14922 In AnnotationSessionFactoryBean, be able to specify annotatedPackages and packagesToScan in one property
- Hibernate Annotation scanner missing package-info.java [SPR-8589] #13233 Hibernate Annotation scanner missing package-info.java
- Support for Hibernate ORM 5.0 [SPR-11694] #16316 Support for Hibernate ORM 5.0
- Add potentially existing orm.xml file to default persistence unit when packages to scan is used [SPR-11260] #15885 Add potentially existing orm.xml file to default persistence unit when packages to scan is used
Referenced from: commits 591f795, 0232739
4 votes, 7 watchers