Annotation-specified bean name conflicts with existing, non-compatible bean def

user1283068 picture user1283068 · Dec 10, 2012 · Viewed 139.9k times · Source

I'm having a problem with some Spring bean definitions. I have a couple of context xml files that are being loaded by my main() method, and both of them contain almost exclusively a tag. When my main method starts up, I get this error from Spring:

Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'converterDAO' for bean class [my.package.InMemoryConverterDaoImpl] conflicts with existing, non-compatible bean definition of same name and class [my.other.package.StaticConverterDAOImpl]

Both DAO classes are annotated this way:

@Repository("converterDAO")
public class StaticConverterDAOImpl implements ConverterDAO {
...
}

The in-memory dao also has the @Repository("converterDAO") annotation. The dao is referenced in other classes like this:

...
private @Autowired @Qualifier("converterDAO") ConverterDAO converterDAO;
...

I want one DAO to override the definition of the other one, which as I always understood it was one of the principal reasons to use a DI framework in the first place. I've been doing this with xml definitions for years and never had any problems. But not so with component scans and annotated bean definitions? And what does Spring mean when it says they are not "compatible"? They implement the same interface, and they are autowired into fields that are of that interface type. Why the heck are they not compatible?

Can someone provide me with a way for one annotated, component-scanned bean to override another?

-Mike

Answer

JB Nizet picture JB Nizet · Dec 10, 2012

In an XML file, there is a sequence of declarations, and you may override a previous definition with a newer one. When you use annotations, there is no notion of before or after. All the beans are at the same level. You defined two beans with the same name, and Spring doesn't know which one it should choose.

Give them a different name (staticConverterDAO, inMemoryConverterDAO for example), create an alias in the Spring XML file (theConverterDAO for example), and use this alias when injecting the converter:

@Autowired @Qualifier("theConverterDAO")