0

How to autowire a generic bean in spring?

I have a dao implement as follows:

@Transactional
public class GenericDaoImpl<T> implements IGenericDao<T>
{

    private Class<T> entityClass;

    @Autowired
    private SessionFactory sessionFactory;

    public GenericDaoImpl(Class<T> clazz) {

        this.entityClass = clazz;
    }
    ...
}

Now I want to autowired the DaoImpl like this:

@Autowired
GenericDaoImpl<XXXEntity> xxxEntityDao;

I config in the spring xml:

<bean id="xxxEntityDao" class="XXX.GenericDaoImpl">
    <constructor-arg name="clazz">
        <value>xxx.dao.model.xxxEntity</value>
    </constructor-arg>
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

But I doesn't work, How should I config it? or a good practice about generic Dao implement?

NingLee
  • 1,477
  • 2
  • 17
  • 26
  • Which spring version? Should work with the 4.x branch of spring. At least that is what I would expect. – M. Deinum Oct 23 '14 at 13:32
  • spring 3.2.8 and hibernate 4.1.1 – NingLee Oct 23 '14 at 13:41
  • Upgrade is then the only option to make it work. It works in Spring 4 (several upgrades have been done in that area for Spring 4) it will not work in versions before that.. – M. Deinum Oct 23 '14 at 13:43

2 Answers2

1

Work with your interfaces instead of implementations

Do not use @Transactional in your persistent layer as it is much more likely that it belongs to your service layer.

Those being said, it might make more sense to extend the generic dao and autowire that. An example would be something like :

public interface UserDao extends GenericDao<User> {

    User getUsersByNameAndSurname(String name, String surname);
    ... // More business related methods
}

public class UserDaoImpl implements UserDao {

    User getUsersByNameAndSurname(String name, String surname);
    {
        ... // Implementations of methods beyond the capabilities of a generic dao
    }

    ...
}

@Autowired
private UserDao userDao; // Now use directly the dao you need

But if you really really want to use it that way you have to declare a qualifier :

@Autowired
@Qualifier("MyBean")
private ClassWithGeneric<MyBean> autowirable;
Pumpkin
  • 1,993
  • 3
  • 26
  • 32
  • But how I should config the bean in spring xml? – NingLee Oct 23 '14 at 14:07
  • or you may directly annotate it – Pumpkin Oct 23 '14 at 14:09
  • And thus, I must config many bean in spring xml for every entity, like UserDao, BookDao, XXXDao... – NingLee Oct 23 '14 at 14:13
  • Yes but you will need that anyway, you need specific dao objects for each of your table as your requirements would be different for them all, and one generic dao may not be able to handle that. It would also improve readability & writability in my opinion – Pumpkin Oct 23 '14 at 14:21
  • And don't configure them in xml, do it by annotation : @Repository public class MyDao ... – Pumpkin Oct 23 '14 at 14:22
0

There is an alternative way.

I change the GenericDaoImpl<T> to a common class without Generic but use the generic in function level, and the entityClass can be configured in spring xml.

NingLee
  • 1,477
  • 2
  • 17
  • 26