Niklas S.
Niklas S.

Reputation: 1054

Spring/Hibernate App only working without @Transactional

I got another problem when working on my current Spring and Hibernate application. I have built my DAO interfaces/classes, as well as my Service interfaces/classes and of course the Entities.

Everything is being deployed well but as soon as I add the @Transactional annotation to my XXXServiceImpl classes, I get the following exception during deployment (tested on Glassfish AND Tomcat):

Caused by: java.lang.IllegalStateException: Cannot convert value of type [com.sun.proxy.$Proxy25 implementing net.dreamcode.bleevle.persistence.service.IntranetService,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [net.dreamcode.bleevle.persistence.service.impl.IntranetServiceImpl] for property 'intranetService': no matching editors or conversion strategy found

Of course, I tried to find something about that and I guess it's basically because interface and class are not matching when adding the annotation. But I also tried adding the annotation on my interfaces, which didn't help along to solve the problem, producing the same error as stated above.

Here's some example code from my project (BasicService, UserService and UserServiceImpl):

BasicService (Interface):

public interface BasicService<T> {

    T findById(String id);
    void create(T entity);
    void delete(T entity);
    void update(T entity);

}

UserService (Interface):

import net.dreamcode.bleevle.data.User;

public interface UserService extends BasicService<User> {

    User findByName(String name);

}

UserServiceImpl (Class):

public class UserServiceImpl implements UserService {

    @Autowired
    UserDao userDao;

    @Override
    public User findByName(String name) {
        return userDao.findByName(name);
    }

    @Override
    public User findById(String id) {
        return userDao.findById(id);
    }

    @Override
    public void create(User entity) {
        userDao.create(entity);
    }

    @Override
    public void delete(User entity) {
        userDao.delete(entity);
    }

    @Override
    public void update(User entity) {
        userDao.update(entity);
    }

    public UserDao getUserDao() {

        return userDao;
    }

    public void setUserDao(UserDao userDao) {

        this.userDao = userDao;
    }
}

Is there a specific thing to do when working with this kind of pattern (I guess it's some kind of design pattern with Service and Dao stuff)?

Any kind of help is greatly appreciated. Thanks in advance!

Upvotes: 0

Views: 143

Answers (1)

William F. Jameson
William F. Jameson

Reputation: 1853

You have a property

@Autowired private IntranetServiceImpl intranetService;

(or an equivalent thereof, such as an annotated constructor parameter or a setter) whose type is the implementation type of your service. This is wrong: you should always use the interface type for your properties.

The reason why it fails as soon, but no earlier than, you annotate with @Transactional is that this annotation causes Spring to create a dynamic proxy of your interface where otherwise there would be the naked implementation class instance. This dynamic proxy fails to be downcast into your implemantation type, but would be successfully cast into the interface type.

Upvotes: 2

Related Questions