Spring Boot scans the compiled files twice, leading to "A bean with that name has already been defined" error. How to properly solve this?
I have a rather simple "Spring Boot" project modeled after the "Tacos" example from "Spring in Action" by manning.com.
So far, I have not used Spring autowiring, but now it's time!
Here we go, absolutely nothing unexpected and the below singleton is injected with "constructor injection" at various points:
package tacos.model.ingredients;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Component
public class IngredientRelation {
@Bean // Indicates that a method produces a bean to be managed by the Spring container.
@Scope("singleton")
public static IngredientRelation ingredientRelation() {
return new IngredientRelation();
}
// etc
}
With no autowiring instructions until now, everything worked fine.
But if I want to start the application now, I get:
The bean 'ingredientRelation', defined in class path resource
[tacos/model/ingredients/IngredientRelation.class], could not be registered.
A bean with that name has already been defined in file
[/home/aloy/IdeaProjects/taco-cloud/build/classes/java/main/tacos/model/ingredients/IngredientRelation.class]
and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting
spring.main.allow-bean-definition-overriding=true
Clearly, the Spring Boot application finds the same class (and actually the same file) twice on its search path.
I don't like the idea of allowing "overriding", it seems like an arbitrary hack.
I would rather have Spring did not scan the same class twice in the first place.
How do I tell Spring Boot to behave?
P.S.
Overriding works though. After adding
spring.main.allow-bean-definition-overriding=true
to file "resources/application.properties", Spring application startup succeeds.
请先登录再写评论。
Hello, D Tonhofer. Could you please share the project via the JetBrains Uploads service and write here the ID you received?
Here it is:
Upload id: 2023_07_14_m32gtzJBDEQw7qRufEm9qa (file: taco-cloud.tar.gz)
You are trying to create a @Bean of type IngredientRelation in the IngredientRelation class, which has the @Component annotation that defines the bean itself.
Thank you, nice.
Still this confuses me a bit.
Getting rid of the static factory method annotated with @Bean and having this
in
src/main/java/tacos/model/ingredients/IngredientRelation.java
@Component
@Scope("singleton")
public class IngredientRelation {
public IngredientRelation() {
// ....
}
...
}
instead of
indeed solves the
error.
Because ... the static factory method is just overkill?
D Tonhofer, thank you for sharing the project.
On my side, it starts successfully in IntelliJIDEA 2023.1.4 with the TacoCloudApplication run configuration, and the application is accessible from the browser. Could you please clarify which IDE version you use?
Thank you Olga,
Yes, sorry about the confusion. It starts normally because I have added
to file "src/main/resources/application.properties".
If you remove it, it doesn't work.
IDEA should be the latest:
But I have tried Ptasiek's suggestion, that works too.
D Tonhofer, I'm glad the solution is found!
Do you need any further help?
Thanks Olga.
It's cool for now, I think I get the problem.