Proxy cannot be cast to CLASS - spring

I'm using Spring for wiring dependencies specifically for DAO classes that use Hibernate, but I'm getting an exception that has me puzzled:
$Proxy58 cannot be cast to UserDao
My DAO is configured as follows:
<bean id="userDao" class="com.domain.app.dao.UserDao">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
And I have an interface, abstract base class and a final implementation as follows.
Interface:
public interface Dao {
public void save(Object object);
public Object load(long id);
public void delete(Object object);
public void setSessionFactory(SessionFactory sessionFactory);
}
Abstract Base Class:
public abstract class BaseDao implements Dao {
private SessionFactory sessionFactory;
#Transactional
#Override
public void save(Object object) {
PersistentEntity obj = (PersistentEntity) object;
currentSession().saveOrUpdate(obj);
}
#Transactional
#Override
public abstract Object load(long id);
#Transactional
#Override
public void delete(Object object) {
// TODO: this method!
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public Session currentSession() {
return sessionFactory.getCurrentSession();
}
}
Implementation:
public class UserDao extends BaseDao implements Dao {
#Transactional(readOnly=true)
#Override
public Object load(long id) {
Object user = currentSession().get(User.class, id);
return user;
}
}
The following throws the exception mentioned above:
UserDao dao = (UserDao) context.getBean("userDao");
This, however, does not throw an exception:
Dao dao = (Dao) context.getBean("userDao");
If anyone can offer any assistance or guidance as to why this exception is happening, I would be very appreciative.

Spring uses JDK dynamic proxies by default ($Proxy58 is one of them), that can only proxy interfaces. This means that the dynamically created type $Proxy58 will implement one or more of the interfaces implemented by the wrapped/target class (UserDao), but it won't be an actual subclass of it. That's basically why you can cast the userDao bean to the Dao interface, but not to the UserDao class.
You can use <tx:annotation-driven proxy-target-class="true"/> to instruct Spring to use CGLIB proxies that are actual subclasses of the proxied class, but I think it's better practice to program against interfaces. If you need to access some methods from the proxied class which are not declared in one of it's interfaces, you should ask yourself first, why this is the case?
(Also, in your code above there are no new methods introduced in UserDao, so there is no point in casting the bean to this concrete implementation type anyway.)
See more about different proxying mechanisms in the official Spring reference.

I was writing unit tests and needed to be able to stub out the DAOs for some calls.
Per This guys post:
http://www.techper.net/2009/06/05/how-to-acess-target-object-behind-a-spring-proxy/
I used his method provided:
#SuppressWarnings({"unchecked"})
protected <T> T getTargetObject(Object proxy, Class<T> targetClass) throws Exception {
if (AopUtils.isJdkDynamicProxy(proxy)) {
return (T) ((Advised)proxy).getTargetSource().getTarget();
} else {
return (T) proxy; // expected to be cglib proxy then, which is simply a specialized class
}
}
Then you can easily call it with the proxy and get the object behind the proxy and manipulate the objects in it directly as needed.

Related

Spring JPA: javax.persistence.TransactionRequiredException: no transaction is in progress [duplicate]

I am new to Spring Transaction. Something that I found really odd, probably I did understand this properly.
I wanted to have a transactional around method level and I have a caller method within the same class and it seems like it does not like that, it has to be called from the separate class. I don't understand how is that possible.
If anyone has an idea how to resolve this issue, I would greatly appreciate. I would like to use the same class to call the annotated transactional method.
Here is the code:
public class UserService {
#Transactional
public boolean addUser(String userName, String password) {
try {
// call DAO layer and adds to database.
} catch (Throwable e) {
TransactionAspectSupport.currentTransactionStatus()
.setRollbackOnly();
}
}
public boolean addUsers(List<User> users) {
for (User user : users) {
addUser(user.getUserName, user.getPassword);
}
}
}
It's a limitation of Spring AOP (dynamic objects and cglib).
If you configure Spring to use AspectJ to handle the transactions, your code will work.
The simple and probably best alternative is to refactor your code. For example one class that handles users and one that process each user. Then default transaction handling with Spring AOP will work.
Configuration tips for handling transactions with AspectJ
To enable Spring to use AspectJ for transactions, you must set the mode to AspectJ:
<tx:annotation-driven mode="aspectj"/>
If you're using Spring with an older version than 3.0, you must also add this to your Spring configuration:
<bean class="org.springframework.transaction.aspectj
.AnnotationTransactionAspect" factory-method="aspectOf">
<property name="transactionManager" ref="transactionManager" />
</bean>
In Java 8+ there's another possibility, which I prefer for the reasons given below:
#Service
public class UserService {
#Autowired
private TransactionHandler transactionHandler;
public boolean addUsers(List<User> users) {
for (User user : users) {
transactionHandler.runInTransaction(() -> addUser(user.getUsername, user.getPassword));
}
}
private boolean addUser(String username, String password) {
// TODO call userRepository
}
}
#Service
public class TransactionHandler {
#Transactional(propagation = Propagation.REQUIRED)
public <T> T runInTransaction(Supplier<T> supplier) {
return supplier.get();
}
#Transactional(propagation = Propagation.REQUIRES_NEW)
public <T> T runInNewTransaction(Supplier<T> supplier) {
return supplier.get();
}
}
This approach has the following advantages:
It may be applied to private methods. So you don't have to break encapsulation by making a method public just to satisfy Spring limitations.
Same method may be called within different transaction propagations and it is up to the caller to choose the suitable one. Compare these 2 lines:
transactionHandler.runInTransaction(() -> userService.addUser(user.getUserName, user.getPassword));
transactionHandler.runInNewTransaction(() -> userService.addUser(user.getUserName, user.getPassword));
It is explicit, thus more readable.
The problem here is, that Spring's AOP proxies don't extend but rather wrap your service instance to intercept calls. This has the effect, that any call to "this" from within your service instance is directly invoked on that instance and cannot be intercepted by the wrapping proxy (the proxy is not even aware of any such call). One solutions is already mentioned. Another nifty one would be to simply have Spring inject an instance of the service into the service itself, and call your method on the injected instance, which will be the proxy that handles your transactions. But be aware, that this may have bad side effects too, if your service bean is not a singleton:
<bean id="userService" class="your.package.UserService">
<property name="self" ref="userService" />
...
</bean>
public class UserService {
private UserService self;
public void setSelf(UserService self) {
this.self = self;
}
#Transactional
public boolean addUser(String userName, String password) {
try {
// call DAO layer and adds to database.
} catch (Throwable e) {
TransactionAspectSupport.currentTransactionStatus()
.setRollbackOnly();
}
}
public boolean addUsers(List<User> users) {
for (User user : users) {
self.addUser(user.getUserName, user.getPassword);
}
}
}
With Spring 4 it's possible to Self autowired
#Service
#Transactional
public class UserServiceImpl implements UserService{
#Autowired
private UserRepository repository;
#Autowired
private UserService userService;
#Override
public void update(int id){
repository.findOne(id).setName("ddd");
}
#Override
public void save(Users user) {
repository.save(user);
userService.update(1);
}
}
This is my solution for self invocation:
public class SBMWSBL {
private SBMWSBL self;
#Autowired
private ApplicationContext applicationContext;
#PostConstruct
public void postContruct(){
self = applicationContext.getBean(SBMWSBL.class);
}
// ...
}
You can autowired BeanFactory inside the same class and do a
getBean(YourClazz.class)
It will automatically proxify your class and take into account your #Transactional or other aop annotation.
Here is what I do for small projects with only marginal usage of method calls within the same class. In-code documentation is strongly advised, as it may look strange to colleagues. But it works with singletons, is easy to test, simple, quick to achieve and spares me the full blown AspectJ instrumentation. However, for more heavy usage I'd advice the AspectJ solution as described in Espens answer.
#Service
#Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
class PersonDao {
private final PersonDao _personDao;
#Autowired
public PersonDao(PersonDao personDao) {
_personDao = personDao;
}
#Transactional
public void addUser(String username, String password) {
// call database layer
}
public void addUsers(List<User> users) {
for (User user : users) {
_personDao.addUser(user.getUserName, user.getPassword);
}
}
}
The issue is related to how spring load classes and proxies. It will not work , untill you write your inner method / transaction in another class or go to other class and then again come to your class and then write the inner nested transcation method.
To summarize, spring proxies does not allow the scenarios which you are facing. you have to write the 2nd transaction method in other class
There is no point to use AspectJ or Other ways. Just using AOP is sufficient. So, we can add #Transactional to addUsers(List<User> users) to solve current issue.
public class UserService {
private boolean addUser(String userName, String password) {
try {
// call DAO layer and adds to database.
} catch (Throwable e) {
TransactionAspectSupport.currentTransactionStatus()
.setRollbackOnly();
}
}
#Transactional
public boolean addUsers(List<User> users) {
for (User user : users) {
addUser(user.getUserName, user.getPassword);
}
}
}

Transactional and Stream in Spring

I try to understand why this code doesn't work
In component:
#PostConstruct
public void runAtStart(){
testStream();
}
#Transactional(readOnly = true)
public void testStream(){
try(Stream<Person> top10ByFirstName = personRepository.findTop10ByFirstName("Tom")){
top10ByFirstName.forEach(System.out::println);
}
}
And repository :
public interface PersonRepository extends JpaRepository<Person, Long> {
Stream<Person> findTop10ByFirstName(String firstName);
}
I get:
org.springframework.dao.InvalidDataAccessApiUsageException: You're trying to execute a streaming query method without a surrounding transaction that keeps the connection open so that the Stream can actually be consumed. Make sure the code consuming the stream uses #Transactional or any other way of declaring a (read-only) transaction.
One key thing about Spring is that many annotated features use proxies to provide the annotation functionality. That is #Transactional, #Cacheable and #Async all rely on Spring detecting those annotations and wrapping those beans in a proxy bean.
That being the case, a proxied method can only be used when invoked on the class and not from within the class. See this about the topic.
Try:
Refactoring and call this #Transactional method from another class in your context, or
By self-autowiring the class into itself and calling the #Transactional method that way.
To demonstrate (1):
public class MyOtherClass {
#Autowired
private MyTestStreamClass myTestStreamClass;
#PostConstruct
public void runAtStart(){
// This will invoke the proxied interceptors for `#Transactional`
myTestStreamClass.testStream();
}
}
To demonstrate (2):
#Component
public class MyTestStreamClass {
#Autowired
private MyTestStreamClass myTestStreamClass;
#PostConstruct
public void runAtStart(){
// This will invoke the proxied interceptors for `#Transactional` since it's self-autowired
myTestStreamClass.testStream();
}
#Transactional(readOnly = true)
public void testStream(){
try(Stream<Person> top10ByFirstName = personRepository.findTop10ByFirstName("Tom")){
top10ByFirstName.forEach(System.out::println);
}
}
}

Spring can you autowire inside an abstract class?

Spring is failing to autowire my object? Is it possible to autowire an object within an abstract class. Assume all schemas are supplied in application-context.xml
Question: What annotation should be on the base and extending classes (if any) #Service #Component?
Example
abstract class SuperMan {
#Autowire
private DatabaseService databaseService;
abstract void Fly();
protected void doSuperPowerAction(Thing thing) {
//busy code
databaseService.save(thing);
}
}
Extending class
public class SuperGirl extends SuperMan {
#Override
public void Fly() {
//busy code
}
public doSomethingSuperGirlDoes() {
//busy code
doSuperPowerAction(thing)
}
application-context.xml
<context:component-scan base-package="com.baseLocation" />
<context:annotation-config/>
I have that kind of spring setup working
an abstract class with an autowired field
public abstract class AbstractJobRoute extends RouteBuilder {
#Autowired
private GlobalSettingsService settingsService;
and several children defined with #Component annotation.
Normally, Spring should do the autowiring, as long as your abstract class is in the base-package provided for component scan.
See this and this for further reference.
#Service and #Component are both stereotypes that creates beans of the annotated type inside the Spring container. As Spring Docs state,
This annotation serves as a specialization of #Component, allowing for
implementation classes to be autodetected through classpath scanning.
What if you need any database operation in SuperGirl you would inject it again into SuperGirl.
I think the main idea is using the same object reference in different classes.
So what about this:
//There is no annotation about Spring in the abstract part.
abstract class SuperMan {
private final DatabaseService databaseService;
public SuperMan(DatabaseService databaseService) {
this.databaseService = databaseService;
}
abstract void Fly();
protected void doSuperPowerAction(Thing thing) {
//busy code
databaseService.save(thing);
}
}
#Component
public class SuperGirl extends SuperMan {
private final DatabaseService databaseService;
#Autowired
public SuperGirl (DatabaseService databaseService) {
super(databaseService);
this.databaseService = databaseService;
}
#Override
public void Fly() {
//busy code
}
public doSomethingSuperGirlDoes() {
//busy code
doSuperPowerAction(thing)
}
In my opinion, inject once run everywhere :)
In my case, inside a Spring4 Application, i had to use a classic Abstract Factory Pattern(for which i took the idea from - http://java-design-patterns.com/patterns/abstract-factory/) to create instances each and every time there was a operation to be done.So my code was to be designed like:
public abstract class EO {
#Autowired
protected SmsNotificationService smsNotificationService;
#Autowired
protected SendEmailService sendEmailService;
...
protected abstract void executeOperation(GenericMessage gMessage);
}
public final class OperationsExecutor {
public enum OperationsType {
ENROLL, CAMPAIGN
}
private OperationsExecutor() {
}
public static Object delegateOperation(OperationsType type, Object obj)
{
switch(type) {
case ENROLL:
if (obj == null) {
return new EnrollOperation();
}
return EnrollOperation.validateRequestParams(obj);
case CAMPAIGN:
if (obj == null) {
return new CampaignOperation();
}
return CampaignOperation.validateRequestParams(obj);
default:
throw new IllegalArgumentException("OperationsType not supported.");
}
}
}
#Configurable(dependencyCheck = true)
public class CampaignOperation extends EO {
#Override
public void executeOperation(GenericMessage genericMessage) {
LOGGER.info("This is CAMPAIGN Operation: " + genericMessage);
}
}
Initially to inject the dependencies in the abstract class I tried all stereotype annotations like #Component, #Service etc but even though Spring context file had ComponentScanning for the entire package, but somehow while creating instances of Subclasses like CampaignOperation, the Super Abstract class EO was having null for its properties as spring was unable to recognize and inject its dependencies.After much trial and error I used this **#Configurable(dependencyCheck = true)** annotation and finally Spring was able to inject the dependencies and I was able to use the properties in the subclass without cluttering them with too many properties.
<context:annotation-config />
<context:component-scan base-package="com.xyz" />
I also tried these other references to find a solution:
http://www.captaindebug.com/2011/06/implementing-springs-factorybean.html#.WqF5pJPwaAN
http://forum.spring.io/forum/spring-projects/container/46815-problem-with-autowired-in-abstract-class
https://github.com/cavallefano/Abstract-Factory-Pattern-Spring-Annotation
http://www.jcombat.com/spring/factory-implementation-using-servicelocatorfactorybean-in-spring
https://www.madbit.org/blog/programming/1074/1074/#sthash.XEJXdIR5.dpbs
Using abstract factory with Spring framework
Spring Autowiring not working for Abstract classes
Inject spring dependency in abstract super class
Spring and Abstract class - injecting properties in abstract classes
Spring autowire dependency defined in an abstract class
Please try using **#Configurable(dependencyCheck = true)** and update this post, I might try helping you if you face any problems.

Get AOP proxy from the object itself

Is possible to get the proxy of a given object in Spring? I need to call a function of a subclass. But, obviously, when I do a direct call, the aspects aren't applied. Here's an example:
public class Parent {
public doSomething() {
Parent proxyOfMe = Spring.getProxyOfMe(this); // (please)
Method method = this.class.getMethod("sayHello");
method.invoke(proxyOfMe);
}
}
public class Child extends Parent {
#Secured("president")
public void sayHello() {
System.out.println("Hello Mr. President");
}
}
I've found a way of achieving this. It works, but I think is not very elegant:
public class Parent implements BeanNameAware {
#Autowired private ApplicationContext applicationContext;
private String beanName; // Getter
public doSomething() {
Parent proxyOfMe = applicationContext.getBean(beanName, Parent.class);
Method method = this.class.getMethod("sayHello");
method.invoke(proxyOfMe);
}
}
This hack is extremely awkward, please consider refactoring your code or using AspectJ weaving. You may feel warned, here is the solution
AopContext.currentProxy()
JavaDoc. I blogged about it here and here.
AopContext.currentProxy() as suggested by Tomasz will work. A more generic solution, that will work outside of the proxied class is to cast the object to org.springframework.aop.framework.Advised and get .getTargetSource().getTarget()
The former (getting the real object from the proxied object) is something that you should not really need. On the other hand getting the target proxy might be useful in some utility class that inspects existing beans in order to add some feature.
You can use a bean post-processor to set a reference to the proxy on the target bean. It moves the Spring-specifics from your beans to a single class.
Post-Processor
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class SelfReferencingBeanPostProcessor implements BeanPostProcessor {
#Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
#Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof SelfReferencingBean) {
((SelfReferencingBean) bean).setProxy(bean);
}
return bean;
}
}
Context
Register the post-processor in applicationContext.xml.
<bean id="srbpp" class="SelfReferencingBeanPostProcessor"/>
Beans
Each bean must implement SelfReferencingBean to tell the post-processor that it needs a reference to the proxy.
public interface SelfReferencingBean {
void setProxy(Object proxy) ;
}
Now implement setProxy in each bean that needs to call itself through its proxy.
public class MyBean implements SelfReferencingBean {
MyBean proxy;
#Override
public void setProxy(Object proxy) {
this.proxy = (MyBean) proxy;
}
}
You could put this last bit of code into a bean base class if you don't mind casting proxy to bean's type when calling methods directly on it. Since you're going through Method.invoke you wouldn't even need the cast.
With a little work I bet this could be converted to an annotation processor a la #Autowired. Come to think of it, I don't recall if I even tried adding a self-reference using #Autowired itself.
public class MyBean implements SelfReferencingBean {
#Autowired MyBean proxy;
}

Dependency Injection into your Singleton

I have a singleton that has a spring injected Dao (simplified below):
public class MyService<T> implements Service<T> {
private final Map<String, T> objects;
private static MyService instance;
MyDao myDao;
public void set MyDao(MyDao myDao) {
this. myDao = myDao;
}
private MyService() {
this.objects = Collections.synchronizedMap(new HashMap<String, T>());
// start a background thread that runs for ever
}
public static synchronized MyService getInstance() {
if(instance == null) {
instance = new MyService();
}
return instance;
}
public void doSomething() {
myDao.persist(objects);
}
}
My spring config will probably look like this:
<bean id="service" class="MyService" factory-method="getInstance"/>
But this will instantiate the MyService during startup.
Is there a programmatic way to do a dependency injection of MyDao into MyService, but not have spring manage the MyService?
Basically I want to be able to do this from my code:
MyService.getInstance().doSomething();
while having spring inject the MyDao for me.
Here is a solution, create a class with a static factory method:
public class MyService {
private static MyService instance;
private MyDao myDao;
public static MyService createInstance(final MyDao myDao) {
instance = new MyService(myDao);
return instance;
}
private MyService(final MyDao myDao) {
this.myDao = myDao;
}
public static synchronized MyService getInstance() {
return instance;
}
public void doSomething() {
// just do it!
myDao.justDoIt();
}
}
and use spring to initilize it:
<bean class="my.path.MyService" factory-method="createInstance" scope="singleton">
<constructor-arg ref="reference.to.myDao" />
</bean>
and now you should be able to do:
MyService.getInstance().doSomething();
without any problems.
If you want a singleton, why not just define that one class in the Spring configs, and it's automatically a singleton (by default).
To avoid initialising at start up, have you looked at Spring lazy initialisation ? Basically you need:
lazy-init="true"
in your bean definition.
As mentioned by others, you should let spring manage your singletons, but if you want to manage them yourself and just let spring inject dependencies, do this:
applicationContext.getAutowireCapableBeanFactory().autowireBean(yourService);
I believe the FactoryBean interface is a good alternative for you. It's a very good choice when you need to execute some initialization logic. For example to start an in memory database or some background processes in separate threads.
You can read more about it in the reference documentation.
An example that demonstrates how I instantiate a database and return a datasource everytime someone wants a bean from the FactoryBean implementation.
#PostConstruct
void init() {
embeddedDatabase = new EmbeddedDatabaseBuilder().addScript(schemaPath)
.addScript(dataPath).setType(embeddedDatabaseType).build();
}
public DataSource getObject() throws Exception {
return embeddedDatabase;
}
This enables loose coupling between the factory logic and the returned object. It's heavily used by the Spring framework internally.
If you want it to be initialized the first time you use it, then set lazy-initialization to true.
Another alternative if you want your code to interact with the Spring container is to create a factory that implements the ApplicationContextAware interface. Then you can do something like this:
myDao = context.getBean(MyDao.class);

Resources