Reputation: 25862
I have the following class hierarchy in my Spring Boot application:
public abstract class A {
private final ObjectMapper objectMapper = new ObjectMapper();
public void method1(Object object) {
this.objectMapper.writeValueAsString(object);
}
}
@Component
public class B extends A {
public void method2() {
method1();
}
}
in such case everything is working fine.
But when I add @Transactional(rollbackFor = Exception.class)
annotation to method2()
declaration, like for example:
public abstract class A {
private final ObjectMapper objectMapper = new ObjectMapper();
public void method1() {
this.objectMapper; // always NULL
}
}
@Component
public class B extends A {
@Transactional(rollbackFor = Exception.class)
public void method2() {
method1();
}
}
and execute method2()
it fails with NullPointerException
in method1()
because of this.objectMapper
is NULL
;
How to let Spring correctly initialize the private final ObjectMapper objectMapper
even in case of @Transactional(rollbackFor = Exception.class)
is added?
Also, in case of @Transactional
annotation the class of this
is B$$EnhancerBySpringCGLIB
and without annotation is just plain B
. So, looks like CGLIB unable to properly initialize private final ObjectMapper objectMapper
.. Is there any workarounds how it can be solved?
Upvotes: 0
Views: 1131
Reputation: 1546
Remove the final
in your code. You are using @Transactional
with CGLIB
. How CGLIB
works is it creates a proxy by extending your class. Since the below method is final it cannot extend it, since final classes cannot be extended.
@Transactional(rollbackFor = Exception.class)
public final void method2() {
method1();
}
Upvotes: 1