TeamCity Inspections (IntelliJ IDEA) and Spring Data - teamcity

TeamCity seems not to recognize Spring Data Repository beans when running the inspections. It works perfectly in IntelliJ IDEA but not in TeamCity.
I receive the following inspection problems:
Warning This custom Spring bean has not yet been parsed And it points to this XML element:
<jpa:repositories base-package="my.base.package" />
And then (obviously) an Error: Could not autowire. No beans of 'MyRepository' type found.
MyRepository extends the Spring Data CrudRepository interface.
As far as I understand, TeamCity launches an IntelliJ instance when running the inspections. Do I have to specify in some way which plugins (Spring Data) IntelliJ has to use when it's running the inspections?
I also tried multiple times to hit the check/reparse button in TeamCity...
Thanks for your help!

Related

#SpringBootTest loads unrequired Bean when making IT

I'm making some Integration Tests for my app and I'm encountering this problem I can't see how to solve.
I'm using Spring Boot 2.4.13 + Spring Data Neo4J 6.1.9
FYI, I deleted the Application default test that comes bundled when you create a project through Spring Initializr, and under /src/test/resources I have a .yml file named application.yml
My IT class looks like this:
#SpringBootTest
public class ClientIT {
#Autowired
private ClientServiceImpl service;
#Autowired
private ClientRepository repository;
#Test
void someTest() {
//Given
//When
//Then
}
}
But when I run this test I get the following Exception:
java.lang.IllegalStateException: Failed to load ApplicationContext
And this is the cause:
Caused by: java.lang.IllegalStateException: The provided database selection provider differs from the ReactiveNeo4jClient's one.
The thing is I don't use SDN's Reactive features at all in my project. I don't even understand why Spring tries to load it. I've created an Issue under the Spring Data Neo4j GitHub repository (https://github.com/spring-projects/spring-data-neo4j/issues/2488) but they could only tell me that ReactiveNeo4jDataAutoConfiguration gets automatically included if there's a Driver or Flux class in the classpath which I don't have.
I've been debugging the Spring internals while booting up the Application after JUnit Jupiter methods to no success.
What I could see is that at some point after JUnit Jupiter tests preparation/initialization, "reactiveNeo4jTemplate" gets injected into DefaultListableBeanFactory's beanDefinitionNames variable.
I've tried many combinations of different annotations intended to be used when making Integration Tests but the one time it worked was after I explicitly excluded ReactiveNeo4jDataAutoConfiguration class through
#EnableAutoConfiguration(exclude=ReactiveNeo4jDataAutoConfiguration.class)
What I've always seen in some blogposts is that by using #SpringBootTest I shouldn't worry about this kind of problem but it looks like I need to add that annotation every time I want to make a new IT test.
My Integration Tests basically consist of bootstrapping the application + web server (tomcat) along with an embedded Neo4J instance and after that, making requests to check everything works as it should. Do I really need to worry about all of this just to make these simple tests?
Thank you
References:
How do I set up a Spring Data Neo4j integration test with JUnit 5 (in Kotlin)?
SprintBootTest - create only necessary beans
Answering my own question after finding what is causing this error:
In the linked Github Issue, one of the developers says having Flux.class in the classpath forces SDN to instantiate Neo4jReactiveDataAutoConfiguration which is what is causing the other reactive beans to instantiate.
Apparently, neo4j-harness brings io.projectreactor (where Flux.class belongs) as an indirect dependency through neo4j-fabric which is the root of our problems.
The Spring Data Neo4j will be fixing this issue in a patch later this week.

Upgrade to Spring Boot 2.1.2 from 2.0.6 causes repository errors

I tried to upgrade a working application from Spring Boot 2.0.6 to 2.1.2. I had some troubles with tests after this change, but eventually got around that. I can successfully build the application from NetBeans (mvn clean install). However, when I try to run from a command line using mvn spring-boot:run, here is what I get:
APPLICATION FAILED TO START
Description:
The bean 'xxxRepository', defined in null, could not be
registered. A bean with that name has already been defined in null and
overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting
spring.main.allow-bean-definition-overriding=true
The interesting part is that every time I try to run it, the error is on a different repository, but always with the same message.
It would seem that this has to do with this change:
Bean Overriding
Bean overriding has been disabled by default to prevent a bean being
accidentally overridden. If you are relying on overriding, you will
need to set spring.main.allow-bean-definition-overriding to true.
Given that it is apparently effecting all my repositories, my guess is that there is a configuration problem somewhere. I can follow the recommended action, but it actually made no difference. The problem is that I don't know what to change in the configuration to get this working again. I'm not even sure what to post that is pertinent to the issue. Any ideas on how to figure this out?
We ran into this issue upgrading from Spring Boot 2.0.x to 2.1.x.
I could "solve" this issue by allowing bean definition override with spring.main.allow-bean-definition-overriding: true but it felt like hiding the root cause.
In fact bean definition overriding used to hide poor configuration on our side.
After inspecting our #Configuration classes we were scanning packages containing our repositories twice, using #ComponentScan and #EnableJpaRepository on the same packages from different classes : once with filters #ComponentScan.Filter, once without.
Removing the second component scan fixed the issue.
I have seen this error before and i had a class BOTH annotated with #Component or #Repository or #Service AND also registered as a #Bean in a config class. Is that your case also by any chance?
I got a similar problem, but it was only with #NotNull annotation. When I upgraded the spring it stopped to work. I tried a lot of things that I found here in SO, but the only thing that worked to me was to eliminate the database and run spring again. I know that it sucks, but didn't find another solution.

Error when trying to use both mongo and sql jpa in the same spring app

We have a spring app that works with mongodb.
Now we need it to connect also to mysql.
All the beans are defined in a applicationContext.xml legacy file.
We like that the new mysql configuration will be in java classes.
We created an entity, repository and a configuraion java files.
But it seems that as we try to do so, spring gets confused.
If we try to run the app, it start complaining about the mongo repositories:
Error creating bean with name 'MyMongoRepository': Could not resolve matching constructor (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities
In the intellij we have the "could not autowire" error only on the sql repository (the first 3 are the mongo repositories):
Is it possible that the #configuration class is clashing with the applicationContext?
Should the #configuraion class be in a certain package/folder to work correctly?
Also, in the #configuration file, as there are green beans on the left side, it seems like intellij is able to understand where is the persistence repository.
Thanks for any help.

How spring framework scans for the annotations and invokes action code for the annotations?

I am trying to understand how Spring (Core spring part at least) works internally.
When we have an annotation like this:
#Autowired(required=true)
private JPADBAccess jPADBAccess;
Which part of the Spring scans this annotation and invokes the code which does the work (in this case injecting the instance)?
Does Spring scan the .class files looking for these annotations and then invoke the code which is supposed to do this work?
I really want to understand the core Spring, and the books which I refer, they don't tell all this (The internal workings or may be I haven't come across any book).
If you want to understand what happens behind the scene of the Spring Framework when it deals with #Autowired, you should do the following steps:
Download Spring source code and attach it to your favorite IDE. For example, in IDEA it is quite simple - just click the "Download sources" button on the Maven toolbar
Search in the Spring sources where the #Autowired is used (in IDEA, press Ctrl+Shift+F, select the "Custom" scope, choose the "Project and Libraries" option, in the "Text to find" type "Autowired.class", the press "Find". You will find all the occurences of the Autowired.class. Actually there will be a couple of occurences, choose the one from the AutowiredAnnotationBeanPostProcessor class. This class exactly scans the #Autowired annotation)
Set a breakpoint at the line where "Autowired.class" is used
Run your example Spring project in the debug mode (in IDEA, Shift+F9)
Once you application is started and the breakpoint is reached, you will see how Spring is scanning your bean where #Autowired dependency is declared.
Look at the "call stack" at the bottom left of the debug window and you will see list of invocations.
Press F8 in order to see how Spring scans your bean step-by-step.
All in all, if you want to understand how some stuff works in Java, just download the sources, set the breakpoints, and run sample project in debug mode.
If you have no sources for the library you want to study, just remember, you can decomile it (e.g. IDEA decompiles classes automatically).
The Spring Core Container does this job.
But it does not simply scan every class files to look for this #autowired annotation.
It only scans the class configured in your project configuration as Spring Beans.
Only objects managed by Spring IOC Container will be instantiated and dependencies injected

Intellij IDEA parse custom bean - cannot find custom handler for namespace

<camel:camelContext id="myCamelContext">
<camel:routeBuilder ref="route"/>
</camel:camelContext>
I try to parse the bean above in Intellij IDEA ("Parse custom bean"), but get the following error:
Cannot find custom handler for namespace 'http://camel.apache.org/schema/spring'
The IDE also displays an error for any corresponding #Autowired annotations in my test code, although the tests run successfully. The application works at runtime, and I have camel-spring as a maven dependency. It only has problems in the IDE.
The camel-spring maven dependency was at "runtime" scope. While technically this is correct, this made it unavailable to Intellij when coding. Changing the maven scope to "compile" enabled Intellij to use the the camel spring bean handler for interpreting the bean.

Resources