Andreas Andersen Kjaer opened SPR-15102 and commented

I am using Spring MVC for REST communication and Hibernate for handling JPA annotations.

I run local system tests with an in memory database and MockMvc.

I have created a class similar to this:

public class BaseEntityListener {

    @Autowired
    private MyService myService;

    private boolean springBeansLoaded = false;

    @PrePersist
    @PreUpdate
    public void updateRowWithTransactionalFields(BaseEntity baseEntity) {
        ensureSpringBeansLoaded();
        .. more code
    }


    private void ensureSpringBeansLoaded() {
        if (!springBeansLoaded) {
            SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
            springBeansLoaded = true;
        }
    }
}

And I have added the class above as an entity listener:

@MappedSuperclass
@EntityListeners(BaseEntityListener.class)
public abstract class BaseEntity {
...
}

My Entities extend BaseEntity.

SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this) works fine when I deploy to an application server. However, when using MockMvc, it does not work. myService will never be assigned as SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext is not capable of finding the application context.

Is this a bug?


Affects: 4.3 GA

Issue Links: - #18264 javax.persistence.EntityListeners annotation generates 2 beans, one without autowired fields

Comment From: spring-projects-issues

Sam Brannen commented

No, this is not technically a bug.

SpringBeanAutowiringSupport uses org.springframework.web.context.ContextLoader.getCurrentWebApplicationContext() to look up the current WebApplicationContext.

However, org.springframework.web.context.ContextLoader is only used if configured via web.xml (i.e., when running in a Servlet container). As stated in the documentation, the Spring MVC Test Framework runs out-of-container. Thus, org.springframework.web.context.ContextLoader is not used in tests, and consequently SpringBeanAutowiringSupport is not supported.

I have reworded the title of this JIRA issue to reflect this.

Comment From: spring-projects-issues

Sam Brannen commented

FWIW, there are alternative approaches for having Spring perform dependency injection on your entity listener, approaches that do not require that your application run in a deployed Servlet container.

For example: https://deepintojee.wordpress.com/2012/02/05/spring-managed-event-listeners-with-jpa/

See also the discussion in the comments section here: #18264

Comment From: spring-projects-issues

Andreas Andersen Kjaer commented

Thank you for the help :)

Comment From: snicoll

There has been some improvements in that area, in particular with Spring implementing BeanContainer from Hibernate that is a more reliable way to do the above.