Skip to content

Manual EntityManager injection into custom repositories

When implementing custom repository logic outside of the standard Spring Data JPA interfaces, a class (e.g., CustomerProfileRepository) may be defined as a standard bean.^[600-developer-java-application-server-weblogic-weblogic-spring-jpa.md] To function, these custom repositories require direct access to the JPA EntityManager, which manages persistence operations^[600-developer-java-application-server-weblogic-weblogic-spring-jpa.md].

In scenarios where the EntityManager is not automatically injected, a manual process is required to bridge the Spring ApplicationContext with the custom repository instance^[600-developer-java-application-server-weblogic-weblogic-spring-jpa.md].

Manual Injection Procedure

The core manual injection method involves retrieving the bean from the application context and using Java Reflection to assign the EntityManager to a specific field within the repository instance^[600-developer-java-application-server-weblogic-weblogic-spring-jpa.md].

The specific steps for this implementation are^[600-developer-java-application-server-weblogic-weblogic-spring-jpa.md]:

  1. Retrieve the target repository bean from the ApplicationContext.
  2. Retrieve the shared EntityManager bean from the ApplicationContext.
  3. Use ReflectionUtils.findField to locate the EntityManager field (typically named em) within the repository class.
  4. Make the field accessible via setAccessible(true).
  5. Use ReflectionUtils.setField to inject the EntityManager bean into the repository instance.

Code Examples

Using Spring XML Configuration

In a test environment using SpringRunner and XML configuration (applicationContext.xml), the ApplicationContext is autowired.^[600-developer-java-application-server-weblogic-weblogic-spring-jpa.md]

The following helper method and test demonstrate the manual injection pattern^[600-developer-java-application-server-weblogic-weblogic-spring-jpa.md]:

@Autowired
private ApplicationContext ctx;

@Test
public void test09() {
    CustomerProfileRepository customerProfileRepository = ctx.getBean(CustomerProfileRepository.class);
    setEm(customerProfileRepository, CustomerProfileRepository.class);
    String levelId = customerProfileRepository.findLevelId(325);
    System.out.println(levelId);
}

private void setEm(Object bean, Class clazz) {
    Field field = ReflectionUtils.findField(clazz, "em");
    field.setAccessible(true);
    EntityManager em = ctx.getBean(EntityManager.class);
    ReflectionUtils.setField(field, bean, em);
}

Using Java Annotation Configuration

When using AnnotationConfigApplicationContext, the same reflection principles apply.^[600-developer-java-application-server-weblogic-weblogic-spring-jpa.md] A generic helper method getBean can be created to retrieve the bean and perform the injection in a single step^[600-developer-java-application-server-weblogic-weblogic-spring-jpa.md]:

[AnnotationConfigApplicationContext](<./annotationconfigapplicationcontext.md>) anno;

private <T> T getBean(Class<T> clazz) {
    T bean = anno.getBean(clazz);
    EntityManager em = anno.getBean(EntityManager.class);
    Field field = ReflectionUtils.findField(clazz, "em");
    field.setAccessible(true);
    ReflectionUtils.setField(field, bean, em);
    return bean;
}

@Test
public void test01() {
    CustomerProfileRepository bean = getBean(CustomerProfileRepository.class);
    String levelId = bean.findLevelId(325);
    System.out.println(levelId);
}

Sources

  • 600-developer-java-application-server-weblogic-weblogic-spring-jpa.md