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]:
- Retrieve the target repository bean from the
ApplicationContext. - Retrieve the shared
EntityManagerbean from theApplicationContext. - Use
ReflectionUtils.findFieldto locate theEntityManagerfield (typically namedem) within the repository class. - Make the field accessible via
setAccessible(true). - Use
ReflectionUtils.setFieldto inject theEntityManagerbean 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
Related¶
- Spring Data JPA
- [[Dependency Injection]]
- [[Java Reflection]]