Skip to content
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

PersistenceAnnotationBeanPostProcessor does not operate on the most specific persistence annotation declaration [SPR-8594] #13238

Closed
spring-projects-issues opened this issue Aug 9, 2011 · 2 comments
Assignees
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

Loïc Frering opened SPR-8594 and commented

Hello guys, I've got an issue with the PersistenceAnnotationBeanPostProcessor
when using multiple persistence units and inheritance. The problem is in
findPersistenceMetadata method which looks for persistence annotations in
registered beans.

The current implementation loops through declared fields and declared
methods of the actual class of the bean to detect eventual persistence
annotation and register a PersistenceElement for each.

And this process is repeated in a do ... while loop for each class in the
inheritance hierarchy of the bean's class.

Here is a simplified verion of the current algorithm:

Class<?> targetClass = clazz;do {
LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<InjectionMetadata.InjectedElement>();
for (Field field : targetClass.getDeclaredFields()) {
// .... currElements.add(new PersistenceElement(field, null));
}
for (Method method : targetClass.getDeclaredMethods()) {
// .... PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
currElements.add(new PersistenceElement(method, pd));
}
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}while (targetClass != null && targetClass != Object.class);
metadata = new InjectionMetadata(clazz, elements);

The problem is that a PersistentElement is registered for each definition of a
field or method in the class hierarchy : the most specific definition is not
the only one registered.

As a consequence having this:

public class GenericRepository {

private EntityManager entityManager;

@PersistenceContext
public void setEntityManager(EntityManager em) {
    this.entityManager = em;
}

// ....}

public class UserRepository extends GenericRepository {

@Override
@PersistenceContext(unitName="my-unit")
public void setEntityManager(EntityManager em) {
    parent.setEntityManager(em);
}

// ....}

Would leed to 2 injected elements in metadata:

  • One for @PersistenceContext without unitName
  • One for @PersistenceContext with unitName "my-unit"

Then Spring injects the EntityManager based on the first element definition and
skip the second one which is the most specific!

There might be a good reason for iterating through each declared field/method
of each super class of the bean's class but I don't get why you do not simply
use the getMethods() and getFields() reflection methods which return the most
specific definition of the field/method with annotations and would avoid having
multiple injectedElements for persistence matadata?


Affects: 3.0.5

Referenced from: commits 65077d2, 49e61d2

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

This turned out to be a bug in the "most specific method" check that we had there anyway: Due to bad ordering, the most specific method only got checked for the @PersistenceUnit annotation but not for @PersistenceContext...

Fixed for 3.1 RC1 as well as 3.0.6 now. Thanks for raising it!

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Loïc Frering commented

Thanks a lot Juergen,

Nice catch on the parenthesis for pc != null && ClassUtils.getMostSpecificMethod! I'm sure that this will resolve a lot of problems for those using multiple persistence units in their projects.

@spring-projects-issues spring-projects-issues added type: bug A general bug in: data Issues in data modules (jdbc, orm, oxm, tx) labels Jan 11, 2019
@spring-projects-issues spring-projects-issues added this to the 3.0.6 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) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants