Should we use #Component on #Entity class in Spring boot - spring-boot

Well i am a newbie in spring boot. I was working on a project where I needed to #Autowired my Entity in a controller class. But I ended up with error:
Field repository in abc required a bean of type 'xyz' that could not be found.
But it solved after adding #Component in Entity class.
So my questions are:
Why Spring boot was not scanning my Entity class as it was under #SpringBootApplication declaration?
When and where we should use #Component annotation in our application?

Use #Component to flag your Pojo as Spring Bean, so that you inject it into other beans with #Autowired
Use #Entity to flag your Pojo as JPA or Spring Data managed bean to read or write it to a database

Related

Spring boot Jpa is not working with Spring batch and spring integration

I am working with spring batch. I needed to add some jpa repositories. So previously i was using JDBCTemplate which was working fine.
But when I started working with JPA, the spring boot application could not find the repos. Which were there.
#Autowired
ClassLevelConfigRepo clcr;
I checked these things as the best practices.
Added #EnableJpaRepositories in springBoot application class.
Added #Repostiories to the repository interfaces.
extended the interfaces with JpaRepository<Account, String>
Added #Entity to the entity classes and defined the #Table and # Column annotations properly.
But I am still getting below error.
Field clcr in com.cloudtask.batchconfig.util.LhmUtility required a bean of type 'com.cloudtask.batchconfig.repo.ClassLevelConfigRepo' that could not be found.
I tried checking all the dependencies in pom.xml it was as per recommended. And I have all the tables defined properly in data base.
I was expecting the application to return the Autowired clcr object propely.
Edit 1 : spring boot application annotations
#SpringBootApplication
#ComponentScan({"com.cloudtask"})
#EnableAsync
#IntegrationComponentScan({"com.cloudtask"})
#EnableIntegrationManagement(defaultLoggingEnabled = "true")
#EnableJpaRepositories
#EntityScan
public class imclassApplication ```
When you work with Spring Data Jpa with those basic points you should also keep track of below points.
you have added spring-boot-starter-data-jpa in your pom.xml
you have added the entity and repo package below one level of the application package.
If you the package is at same level you should specify the exact package details in the annotation. in your case it should be like :
#EnableJpaRepositories("com.cloudtask.batchconfig.repo")
#EntityScan(basePackages = {"com.cloudtask.batchconfig.entity"})
Happy programming!

Should I annotate Spring Data Repositories with #Repository [duplicate]

I'm using Spring Data JPA repositories (like MyRepo extends JpaRepository) and it works without #Repository and without #EnableJpaRepositories annotations. Could someone explain why?
Probably you are using Spring Boot.
Spring Data repositories usually extend from the Repository or CrudRepository interfaces. If you use auto-configuration, repositories are searched from the package containing your main configuration class (the one annotated with #EnableAutoConfiguration or #SpringBootApplication) down.
Please check the Spring Boot Reference Documentation (v2.7.2) for more details.
you don't need #Repository to make use of Spring Data JPA.
The Interface extending the CrudRepository or JPARepository would work even without annotating it with #Repository.
The Core reason why you need to have this annotation in place is it makes unchecked exceptions thrown in the DAO layer eligible to be translated into Spring DataAccessException. Which in turn would be easier to work with. This is the important aspect of using #Repository
More details see this -> https://www.youtube.com/watch?v=z2re1MfWtz0&list=PLO0KWyajXMh4fGMvAw1yQ1x7mWayRcmX3&index=8&t=0s
For more information look into these class which is used to auto-configure Spring Data JPA Repositories:
JpaRepositoriesAutoConfigureRegistrar
Docs : http://www.atetric.com/atetric/javadoc/org.springframework.boot/spring-boot-autoconfigure/1.2.0.RELEASE/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesAutoConfigureRegistrar.html
#EnableJpaRepositories
private static class EnableJpaRepositoriesConfiguration {
}

Spring Hibernate won't implement Repository Class from Interface

I have two separate projects. One project contains my Application logic and Controllers in org.patrick.application, and one separate project contains my Hibernate entities, Dao, and models in org.patrick.hibernate. My problem is that Spring will not instantiate a implementing class for my CrudRepository.
Here is my Application.java class annotations in my Application project:
package org.patrick.application;
#SpringBootApplication
#Configuration
#EnableAutoConfiguration
#EnableTransactionManagement
#EnableJpaRepositories(basePackages = { "org.patrick.hibernate" })
#EntityScan(basePackages = { "org.patrick.hibernate" })
#ComponentScan(basePackages = { "org.patrick.hibernate", "org.patrick.application" })
These annotations should scan my second Hibernate project for all of my Hibernate objects.
My Hibernate repository looks like this:
package org.patrick.hibernate;
#Repository
public interface PatrickDao extends CrudRepository<MyModel, Long>
This repository does not have a class implementation. I am expecting Spring to populate this implementation for me.
Now, inside of my application org.patrick.application, I am trying to use the Dao like so:
package org.patrick.application;
#Autowired
private PatrickDao patrickDao;
This is causing my Application project to fail to start because of the following error:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean found for dependency [org.patrick.hibernate.PatrickDao]: expected at least 1 bean which qualifies as autowire candidate.
I know that the core problem is that Spring is not implementing this interface -
because if I provide my own PatrickDaoImpl in the org.patrick.hibernate package, then the Application project will start just fine. This confuses me because I have the proper annotations on my Application.java class, and yet the Repository cannot be implemented by Spring for some reason.
Is there anything further I need to do in order to get Spring to implement the class for my Repository interface? In previous testing, this behavior works if everything is under the same package.
I found the problem. For this particular Model, the definition looked as such:
package org.patrick.hibernate;
public class MyModel implements Serializable {}
This Model did not have the #Entity annotation. If this annotation is missing, then Spring will give no warnings as to why it cannot implement the repository interface. In my case, it simply threw the NoSuchBeanDefinitionException exception.
I updated my Model with the proper annotations:
package org.patrick.hibernate;
#Entity
public class MyModel implements Serializable {}

spring boot #autowired filed injected with null in the #configuration class but worked with #import

According to the reference using-boot-configuration-classes, I used #ComponentScan on the Application class and use the #Configuration on my config class, in my config class, I want to inject beans defined in other config class by using #Autowired annotation, but when I run the application, I got null for these fields, I tried to use import on the application and remove the #Configuration from config class, everything works fine.
Is it a bug of spring boot or I am misunderstanding about the usage of #Configuration annotation?
Are you trying to autowire other configuration classes into Application class?
Use a fresh method along with #PostConstruct to make it call automatically after Spring creates an instance of Application class.

When to use Spring #Autowire annotation

Recently I had discussion with my friend regarding usage of Spring #Autowire annotation on entity(JPA) classes.
In our project we are using #Autowire annotaion to inject Entity but my friend suggesting not to use #Autowire annotaions on entity classes. When I asked why? He dont have the proper answer for that. So i just wanted to know are there any disadvantages using #Autowire annotaion on entity classes.
Also please explain when to go for #Autowire annotaion or not with example.
Thank in advance.
#Entity and #Autowire are not interchangeable.
#Entity annotation indicates that the JavaBean is a persistent entity.This is actually a JPA annotation and not a Spring Annotation.
#Entity will be used in the sessionFactory by the packagesToScan poroerty.
#Autowired: inject a resource by-type, i.e. by the class or by the interface of the annotated field or contractor. See my answer Inject and Resource and Autowired annotations
#Autowired is used to inject dependencies as an alternative to setting it via xml configurations
Maybe this answer will help you understand
Hibernate - spring annotated entities not scanned from within jar
UPDATE:
Following the comment bellow:
Company is your domain object, so you don't need to use spring in this case.
<bean id="company" class="xxx.Company"/>
The above will return the same instance with #autowire.
Even if you switch to scope="prototype" I don't see any reason to use spring for that.
You should have a service that will be used to CRUD company e.g.
CompanyService, this service will be a single tone so you will use #Autowire to inject it to the controller and it will use your JPA framework to implement CRUD's
To create a new company you will use:
Company c = new Company //this probably will be binded from your ui form
companyServic.saveOrUpdate(c);
See the following answer spring rest service - hibernate dao - annotations - pojo - namedqueries.
For common practice of DAO and services.
#Autowire is an annotation used to perform a dependency injection, its almost similar to the standard #Inject you can take a look at the spring reference manual to see the difference between those two annotations.
#Entity is a part of the jpa framework its used to mark a class as persistent, spring does not implement an equivalent annotation.

Resources