Does it make sense to use PersistenceExceptionTranslationPostProcessor with Spring's JdbcTemplate? - spring

Title speaks for itself.
Is PersistenceExceptionTranslationPostProcessor used solely for JPA implementations or is it relevant to use it with Spring's JdbcTemplate too?
And if there are two datasources needed each with their own JPA entity manager and transaction manager, do I still only need to specify one PersistenceExceptionTranslationPostProcessor for the entire application?

The auto-award bounty answer is wrong
~~~The correct answer is as follows~~~
I believe I've discovered the answer here:
http://www.deroneriksson.com/tutorials/java/spring/introduction-to-the-spring-framework/component-scanning-and-repository
The #Repository annotation can have a special role when it comes to converting exceptions to Spring-based unchecked exceptions. Recall that the JdbcTemplate handled this task for us. When we work with Hibernate, we’re not going to work with a Spring template that handles this conversion of Hibernate-based exceptions to Spring-based exceptions. As a result, in order to handle this conversion automatically, Hibernate DAOs annotated with #Repository will have their Hibernate exceptions rethrown as Spring exceptions using a PersistenceExceptionTranslationPostProcessor.
Further reading: http://www.deroneriksson.com/tutorials/java/spring/introduction-to-the-spring-framework/hibernate-daos
The paragraph above explicitly says:
Recall that the JdbcTemplate handled this task for us
So, to answer my own question, there is no need to use PersistenceExceptionTranslationPostProcessor with jdbcTemplate

Yes you can, The Spring exception translation mechanism can be applied transparently to all beans annotated with #Repository – by defining an exception translation bean post processor bean in the Context:
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
As per it doc
Bean post-processor that automatically applies persistence exception translation to any bean marked with Spring's #Repository
annotation, adding a corresponding
PersistenceExceptionTranslationAdvisor to the exposed proxy (either an
existing AOP proxy or a newly generated proxy that implements all of
the target's interfaces).
Translates native resource exceptions to Spring's DataAccessException hierarchy. Autodetects beans that implement the
PersistenceExceptionTranslator interface, which are subsequently asked
to translate candidate exceptions.
All of Spring's applicable resource factories (e.g. LocalContainerEntityManagerFactoryBean) implement the
PersistenceExceptionTranslator interface out of the box. As a
consequence, all that is usually needed to enable automatic exception
translation is marking all affected beans (such as Repositories or
DAOs) with the #Repository annotation, along with defining this
post-processor as a bean in the application context.
So you can use it with Jdbctemplate as well as with any Jpa vendor implementation
As per is doc All of Spring's applicable resource factories (e.g. LocalContainerEntityManagerFactoryBean) implement the PersistenceExceptionTranslator interface out of the box, I think you still need to use PersistenceExceptionTranslationPostProcessor, because it used to translate all errors generated during the persistence process (HibernateExceptions, PersistenceExceptions...) into DataAccessException objects.

Related

What is the replacement of EJB SessionContext object in spring boot?

I am migrating an EJB project to Spring boot project. I have successfully replaced other annotations to the spring annotation, but havving problem with SessionContext object.
My legacy code is bellow
#Resource
SessionContext sessionContext;
.....
if (some condition) {
sessionContext.setRollbackOnly();
return false;
}
For this code i am getting the following error
A component required a bean of type 'javax.ejb.SessionContext' that could not be found.
Action:
Consider defining a bean of type 'javax.ejb.SessionContext' in your configuration.
I think you'll have to use a few different functionalities.
setRollbackOnly()
Most often I have seen Session Context used for Rollbacks. In Spring, you can replace this with:
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
or annotate class with
#Transactional(rollbackFor = MyException.class)
so you can throw your exception from class to cause rollback.
getBusinessObject()
The second most commonly used feature is method to load a business object so that I can, for example, create a new transaction within a same bean. In this case you can use Self-inject:
#Lazy private final AccountService self;
and annote method with #Transactional. This, of course, solves any other cases where you need to use the power of a proxy object.
Other functionality is provided by other classes in Spring, but I think that these two are the most commonly used in the Java EE world and when migrating, one will look to replace them in Spring.

can we make exceptions(thrown from DAO methods) eligible for Spring DataAccessException without using #Repository annotation in DAO

what if i don't annotate DAO classes with #Repository, will that still makes the unchecked exceptions (thrown from DAO methods) eligible for translation into Spring DataAccessException?? Can anyone expain this? bit confused with #Repository annotation
Definition of #Repository given on this link
Indicates that an annotated class is a "Repository", originally
defined by Domain-Driven Design (Evans, 2003) as "a mechanism for
encapsulating storage, retrieval, and search behavior which emulates a
collection of objects".
Teams implementing traditional J2EE patterns such as "Data Access
Object" may also apply this stereotype to DAO classes, though care
should be taken to understand the distinction between Data Access
Object and DDD-style repositories before doing so. This annotation is
a general-purpose stereotype and individual teams may narrow their
semantics and use as appropriate.
A class thus annotated is eligible for Spring DataAccessException
translation when used in conjunction with a
PersistenceExceptionTranslationPostProcessor. The annotated class is
also clarified as to its role in the overall application architecture
for the purpose of tooling, aspects, etc.
what if I don't annotate DAO classes with #Repository, will that still
makes the unchecked exceptions (thrown from DAO methods) eligible for translation into Spring DataAccessException??
No,Because as per details given on this link
Bean post-processor that automatically applies persistence exception
translation to any bean marked with Spring's #Repository annotation,
adding a corresponding PersistenceExceptionTranslationAdvisor to the
exposed proxy (either an existing AOP proxy or a newly generated proxy
that implements all of the target's interfaces).
Hope this will help you understand!!

Autowired spring bean is not a proxy

I'm working on a very small application connecting to a MySQL database.
I'm trying to create table record but getting 'no transaction in progress'.
I have all the right stuff in place:
a service interface MyService and its implementation MyServiceImpl
I have annotated the service impl with #Service
In the controller I used the interface name for the field #Autowired MyService
I have the correct transaction configuration as it was originally generated by roo
There is a public method MyService.create(...) which MyServiceImpl implements
But,
When I remote debug and inspect the controller's myService field what I see is something like
com.some.package.services.MyService#12345 (and NOT something like $Proxy73) which to me is not right, because what should be autowired is the proxy not he target bean (which is what I think this is). If I'm correct then it makes sense that there is no transaction as the annotation would only kick in when invoking a public method annotated with #Transactional on a proxy.
Please tell me why is spring injecting the target bean in this setup.
Thanks
If you have AspectJ-enabled transaction management (<tx:annotation-driven mode="aspectj" .../>) application of transactions happens in-place in the same class, either during build (compile-time weaving) or on startup (load-time weaving).
No new classes are created (like when using cglib) and no proxies (like with ordinary interface-based AOP in Spring). Instead bytecode of MyServiceImpl was modified directly without you even noticing. Unfortunately the only way to see AOP is to decompile your classes. If you use javap -c MyServiceImpl you'll find plenty of references to Spring transaction layer.
If you are using Spring MVC, make sure to scan specific controller classes alone in servlet context file. Otherwise it will scan 2 times and transaction is not available on the application context.

Does this annotation work for Spring declarative transaction

As far as I know, Spring uses JDK to generate dynamic proxy for the classes that implement any inferface while use Cglib to generate dynamic proxy for the classes that do not implement any inferface. For decarative transcation, Spring uses proxy to add transaction aspect. Please take a look at the code below:
interface Demo {
void methodA();
}
public class DemoImpl implements Demo{
#Transactional
public void updateA() {}
#Transactional
public void updateB() {}
}
I think updateA can work well with transaction. But how about updateB method? Does the #Transactional work for it?
Maybe my understanding is not correct. It's great if the related Spring source code is provided to explain how Spring use JDK/cglib to proxy the class and interface. Thanks
I have the config in the xml:
<tx:annotation-driven transaction-manager="transactionManager" />
JDK dynamic proxy
In this case your bean is wrapped with a proxy implementing Demo interface. From that moment you can only use that interface. Trying to inject or fetch bean of DemoImpl type will result in dreadful Abstract DAO pattern and Spring's "Proxy cannot be cast to ..." problem!
This kind of answers your question - you can only access updateA() and this is the only transactional method. Annotation around updateB() is ignored.
However if you call updateB() from updateA() it will be transactional because it will bind to a transaction started by updateA() (with default transaction propagation).
CGLIB proxy
In this case the interface is ignored. cglib will create a subclass of DemoImpl (obviously also implementing Demo interface) and apply transaction behaviour on both update*() methods. Now if you inject bean of type DemoImpl (interface is not needed in this case at all and Impl suffix is ugly) you can safely and transactionally call both methods.
See my article: Spring pitfalls: proxying and Spring AOP riddle for greater details.

hibernate validator without using autowire

I'am currently working on a Jersey project and decided to use Hibernate validator for the parameter validations. All dependencies injected on the Endpoint classes are properly initialized. However for those dependencies in the ConstraintValidator classes, it always throw a NPE. So i followed the guide on Spring+hibernate guide and registered
bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"
and used the #Autowired annotation for the services in the ConstraintValidator class which needs to be injected.
are there side effects of using it? Is there a way to avoid the autowiring annotation in ConstraintValidator class and still injecting the values? I tried manually registering the constraintValidator class in the context as bean, adding a property reference to the service that i need, however it throws a null pointer exception.
"Hibernate Validator - JSR 303 Reference Implementation - Reference Guide" says something about portality:
Warning
Any constraint implementation relying on ConstraintValidatorFactory
behaviors specific to an implementation (dependency injection, no no-arg
constructor and so on) are not considered portable.
So, is it a bad thing? In my opinion it's not. Of course you are now coupled to the DI container (Spring) and can't easily reuse validators (e.g. when not using Spring). On the other hand, with your validators build by a Spring factory you can take full advantage of the framework and do very heavy lifting (read revision data for entities and comparison of previous states, call arbitrary services, enhance or localize validation messages, ...).
One thing you must be very careful about is that a validator's semantics is normally read-only and should not cause side-effects by calling it. For example don't accidentally flush data to the database because of some auto-flushing by invoking a (transactional) service or reading data inside your validator.

Resources