Skip to content

EntityManagerFactoryUtils.findEntityManagerFactory() does not search parent contexts if persistence unit name is unspecified [SPR-10160] #14793

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue Jan 10, 2013 · 0 comments
Assignees
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) status: backported An issue that has been backported to maintenance branches type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

Tim Yates opened SPR-10160 and commented

Bottom line:

When EntityManagerFactoryUtils.findEntityManagerFactory() is called with a persistence unit name, it looks for an EntityManagerFactory bean through the whole context hierarchy. If the persistence unit name is omitted, it will only look at the current context and ignore beans in any parent context.

Why this matters:

I have a Spring MVC application that has a global context in /WEB-INF/applicationContext.xml and an MVC context in /WEB-INF/dispatcher-servlet.xml. The EntityManagerFactory is configured in the global context, and we have an OpenEntityManagerInViewInterceptor in the MVC context. If I leave the OEMIVInterceptor's persistenceUnitName property undefined, the application fails to start up with this error:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [javax.persistence.EntityManagerFactory] is defined: expected single bean but found 0
    at org.springframework.beans.factory.BeanFactoryUtils.beanOfType(BeanFactoryUtils.java:394)
    at org.springframework.orm.jpa.EntityManagerFactoryUtils.findEntityManagerFactory(EntityManagerFactoryUtils.java:111)
    at org.springframework.orm.jpa.EntityManagerFactoryAccessor.setBeanFactory(EntityManagerFactoryAccessor.java:139)
    at ...

However, if I specify the persistenceUnitName, all is well. This also worked previously when all the beans were defined in one context (without the need to specify the persistence unit).

If this is not a bug, I fail to see the logic behind it. Here is the relevant snippet from EntityManagerFactoryUtils.findEntityManagerFactory():

if (StringUtils.hasLength(unitName)) {
    // See whether we can find an EntityManagerFactory with matching persistence unit name.
    String[] candidateNames =
        BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, EntityManagerFactory.class);
    // ...
}
else {
    return BeanFactoryUtils.beanOfType(beanFactory, EntityManagerFactory.class);
}

As you can see, it calls the "...IncludingAncestors" method if the persistence unit name is defined, but uses the no-hierarchy version otherwise. This could easily be fixed by changing the second call to:

else {
    return BeanFactoryUtils.beanOfTypeIncludingAncestors(beanFactory, EntityManagerFactory.class);
}

Affects: 3.1.3, 3.2 GA

Referenced from: commits 1a929f2, 50ed863

Backported to: 3.1.4

@spring-projects-issues spring-projects-issues added in: data Issues in data modules (jdbc, orm, oxm, tx) status: backported An issue that has been backported to maintenance branches type: enhancement A general enhancement labels Jan 11, 2019
@spring-projects-issues spring-projects-issues added this to the 3.2.1 milestone Jan 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) status: backported An issue that has been backported to maintenance branches type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants