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

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 {
}

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!

Why is SimpleJpaRepository injected as a default CrudRepository?

In Spring Boot (Spring Data) project a custom repository (i.e. UserRepository) extends CrudRepository provided by Spring. At runtime I see that the actual implementation that is injected is SimpleJpaRepository.
Since I do not specify any classes to inject I'd like to better understand how does Spring know to inject this particular class?
I understand that by default Spring autowires by type, but SimpleJpaRepository is not the only implementation of CrudRepository, there are others, such as QuerydslJpaRepository.
SimpleJpaRepository is the default implementation of CrudRepository. That's the reason it is injected. Please refer here

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.

Spring-data-mongo: MongoRepository not being wired unless I add #Component annotation

I am having a little weird behavior with my spring-data-mongo where my repository package is not being scanned by the <mongo:repositories/> tag. I am using spring 3.2.3.RELEASE with spring-data-mongo 1.2.1.RELEASE.
I have a project called edowmis and in it there are 2 maven modules, datalayer and web which a webapp.I am using the datalayer in isolation so the other module can be ignored. I have an application context for datalayer
So I wanted to test my setup by writing a small Unit/Integration test but I've noticed I can't autowire my UserRepository because It says there isn't such a bean
Since I am using IntelliJ I can see certain visuals when things are ok and not ok. I've addec <context:component-scan/> to my application context but no result.
But when I add the #Component annotation it has started identifying the Class.
all information you might need is on pastie.org
Is the #component or #Repository really necessary or something is wrong with my configuration?
Yes, the #Component or #Repository is necessary. The scan simply indicates that spring should look for classes identified via annotations (#Component, #Repository, #Service) and load them as beans. If you don't use repository or component scan, you would have to manually instantiate all spring-managed beans via XML configuration or Java configuration.
You have to tell spring which classes to turn into beans as it doesn't assume everything in the classpath is supposed to be a spring-managed bean, which is why you need to use the annotations.

spring data like functionality for JEE6

I have experience building applications on the Spring Framework primarily. I was wondering if there was anything similar to the Spring Data API (to support a Data Access Layer) in the JEE6 space?
I know I can wire in an entity manager like:
#PersistenceContext
EntityManager em;
Ideally I would like to avoid writing reams of boiler plate JPA code on Data Access beans, is an API similar to SpringJPA which can help cut down on the amount of boilerplate code such as findAll(), findByX() etc. For example, with SpringJPA I can define a bean as:
#Repository
public interface FooRepository
extends JpaRepository<Foo, String>
{
}
Whereas in vanilla JEE6 I would need a
a FooRepository interface with methods Foo findOne(Long), List<Foo> findAll()
a FooRepositoryImpl which implements the interface and interacts with the EntityManager
Spring Data JPA ships with a CDI extension to simply #Inject a repository into your CDI managed bean. See the reference documentation for details. The approach still requires Spring JARs on the classpath but no container being bootstrapped. This functionality is also available for MongoDB repositories.

Resources