How can I do CRUD operations through CrudRepository in Spring? - java

I'm working with PostgresSQL and I have the following interface:
#Repository
public interface ExampleRepository extends CrudRepository<ExampleEntity, Long> { }
Then I try to get the bean:
ExampleRepository repository = ctx.getBean(ExampleRepository.class);
Of course, I can't do that, because there's no implementation and eventually I get
NoSuchBeanDefinitionException: No qualifying bean of type 'ExampleRepository'
I know this is a wrong approach, but since I'm not enough experienced, I've got no idea how I can communicate with my database. Any example I searched only explained how to implement services & controllers in order to interact with db through Browser. But I want to do CRUD operation inside the java code.
Could anyone explain it to me? Any related sources would also be fine.

I am not sure how you are getting context (ctx) here.
But the common approach is #Repository is not needed instead, #EnableJPARepositories should be used in the #Configuration file. Then use #Autowired to inject the repository into your service class (where you want to execute operation from your repository bean)
You can refer below link for more details
https://mkyong.com/spring-boot/spring-boot-spring-data-jpa/

You don't need to create bean. It will created by the spring framework because you annotated your interface as #Repository .You need only #Autowired in your service class or where do you want to use this reference.
#Autowired
private ExampleRepository exampleRepository;

Related

How to make Depedency Inject in a not "RequestMapping" method

Can i make my repository be accessed in a class who isn't a RestController or something like that ?
I have an WatchService who listen a folder, to reads the files and after persist to a database. My watchservice works just like reading files, but I want persist using my JPARepository to persists, can i do that?
Springboot Application v2.1.6.RELEASE
#Repository
public interface MyRepository extends JpaRepository<MyClass, Long> { }
public class MyWatchService implements Runnable{
#Autowired
private MyRepository myRepository;
// SOME CODES COMES HERE
#Override
public void run() {
// SOME CODES COMES HERE
myRepository.save(MyClass); // In this point give a nullPointerException
}
}
I get that Exception:
java.lang.NullPointerException
at com.WatchService.run(WatchService.java:515)
at java.base/java.lang.Thread.run(Thread.java:835)
You get the NullPointerException because the dependency did not get injected. You used the annotation correctly, but the dependencies do not get injected, by some magic.
In order for this to work (i.e. for the beans to get injected), you need to let the DI- or IoC Container instantiate the bean for your (in JEE this would be CDI, in Spring it is the Spring IoC Container). This can be done by injection (d'uh! Injection-inception) or programmatically.
A Spring-centric solution is explored in this question.

Autowire all components in a package without implementing an interface

I got a project with tons of services and repositories. Currently each repository is autowired to a service using annotations.
#Service
public class Service1 {
#Autowired
private Repository1 repository1;
#Autowired
private Repository2 repository2;
...100+ more
}
All of these repository are under the same package. Is it possible to skip declaration for each repository?
A simple solution I found would be to implement an interface like this:
#Autowired
private Map<String,RepositoryInterface> repositoryInterface
public void method1(){
repositoryInterface.get("repository1").doMethod();
}
It should have been a good solution but problem is I don't have access to all the source codes. I have tons of repository classes that I am not allowed to change to add an interface class.
So is there another way to solve this? Like just scan the whole package and just use bean name to access the repositories?
Beans are retrievable from their class or their name (and both).
In your case, you could rely directly on their class to retrieve them from the context.
Inject an ApplicationContext (or constructor way) :
#Autowired
private ApplicationContext applicationContext;
And use it :
applicationContext.getBean(RepositoryOne.class).doMethod1();
Ideally it should be extracted into a method :
public <T> T getRepository(Class<T> clazz){
return applicationContext.getBean(clazz);
}
to be used more simply :
getRepository(RepositoryOne.class).doMethod(1);
But I would warn about needing so many field dependencies in a class.
This makes it very hard to maintain/to test and also very error prone to use.
The best thing to do is rethink your design to avoid such complex/bloat class.
Besides using structure like private Map<String,RepositoryInterface> repositoryInterface or ApplicationContext will make you lose the benefit from dependency checks performed by the Spring container at startup that prevents NullPointerException and errors related to inconsistency (dependency missing) during the application working.

Spring functional bean registration of #Repository interface

I migrated a Spring-Cloud-Function to use Functional Bean Registration.
I can register the Function that contains my application logic.
However my logic should be able to autowire a dynamodbRepository which I currently defined like this:
#EnableScan
public interface BookRepository extends CrudRepository<CodingTip, String> {
List<Book> findAllByAuthor(String author);
}
Since I am not scanning for beans anymore no bean is created of type BookRepository. This means that I have to register it myself. But I do not want to define the implementations of all the CRUD methods.
Currently I could write:
context.registerBean("repository", BookRepository.class, () -> new BookRepository(){ ... });
How would I register the BookRepository bean while still maintaining the advantages of all the CRUD methods being implemented for me?
Check out this incubator project called Spring Fu. Although it is written in Kotlin, it might help you find a way to do this.
Take a look here to see how Sébastien did it with a MongoDB database.
Creating a DynamoDB client and an implementation instead of using an annotated interface would be the way forward I guess.
Hope that helps! :)

How to set the attributes to a generic #Service class in Spring Boot?

I'm new to Spring Boot, so bare me with my basic question here.
I want to build a generic #Service class that has well defined methods that don't even need to be overwritten.
The only thing this class needs is to adjust its attributes based on which Controller method was called. Basically, this class works as a Job handler that needs to adjust some parameters so its methods can perform what they're supposed to compute. The job will always have the same workflow, calling the methods in the same order, but it will obtain different results depending on the parameters/attributes it receives, which, as I said before, are defined by the controller methods.
The only attribute it has beside the ones that adjust the job's workflow is an autowired #Repository object that will save the results of the job in a database.
Maybe I could simply instantiate an Job Handler object and call a constructor with the paramaters I need for the job, but I don't know what is the "Spring way" of doing this, considering how Spring works with dependency injection and I need a #Repository object embbeded into the Job Handler service.
I would really appreciate if anyone could write a sample code/example so I could understand how this can be done with Spring Boot so I don't have to duplicate code or Service Classes.
The Spring way for this case would be to create a Bean of your JobHandler, where you inject the necessary dependencies, like your Repository:
#Configuration
class MyConfiguration {
#Bean
MyJobHandler myJobHandler(MyRepository myRepository) {
return new MyJobHandler (myrepository);
}
}
Alternatively, if you do not want a configuration class, you could declare your JobHandler as a Component and inject the repository in the constructor:
#Component
class MyJobHandler {
private MyRepository myRepository;
public MyJobHandler myJobHandler(MyRepository myRepository) {
this.myRepository = myRepository;
}
}

Using repository annotation when implementing JpaRepostiory in Spring

I'm not sure if I understand it correctly so want to clarify.
If I want to create a repository for my entity eg.:
public interface BookRepository extends JpaRepository<Book, Id> {}
Should I annotate it with #Repository? According to this question #Repository annotation translates exceptions from SQL to persistence ones but doesn't JpaRepostiory already do that? What's the best practice - to annotate or not?
While using JpaRepository you don't need to annotate the interface with #Repository
It is just an interface and the concrete implementation is created dynamically as a proxy object by Spring and the JDBC Exceptions are handled there.
You need to use #Repository when you create a Custom DAO, so that spring creates a bean and handles the exception properly.
You need to annotate it with #Repository so spring knows it should instantiate that class as a bean. The #Component, #Service and #Repository annotations all serve the same purpose in that regard. #Repository narrows the scope to a service that specifically deals with obtaining and storing data.

Categories