1

I am trying to really understand how those Interfaces in Java work. As I know, it's kinda used to describe what implementing classes will do but not how to do that. That's clear enough for me.

The problem is, when I try to use CrudRepository interface from Spring Data package, then I don't really know how it works. I create for example CarRepository which extends CrudRepository interface without adding any new methods. After this I create CarService class which injects CarRepository via CarService constructor for dependency Injection.

Regarding to that I use save method from CarRepository and I am totally lost because I don't know, how it's possible that it's really saving the passed object to the database. The reason is, that this save method has no 'body', so that how does it know, how to insert to to the database?

The example of the code:

class CarService{
     private CarRepository carRepository;
     public CarService(CarRepository carRepository){
           this.carRepository = carRepository;}

     public Car saveCar(Car car){
     Car savedCar = carRepository.save(car);
     return savedCar;

}


}
}

Can you guys please clarify me, how is that possible that this method saves the car object to the any database configured to the spring? Cuz there is no body of save method, so how does it know how to do that?

3
  • It's not at all related how interfaces work in Java. It is about the magic done behind the scenes by spring.data Commented Dec 21, 2017 at 11:09
  • also: if you don't know how interfaces work, don't use frameworks yet, but study the basics. Commented Dec 21, 2017 at 11:11
  • From the description, it sounds like Spring is creating a class from your CRUD interface at runtime? Try to log or print the value of carRepository.getClass().getName(); it will probably be something like CGLib$something or Javassist$something, indicating that they were dynamically created via either CGLib or Javassist. Commented Dec 21, 2017 at 11:13

2 Answers 2

3

Normally, to be able to use an interface in a Java application, you will also need at least one non-abstract class that implements the interface - otherwise there is indeed nothing to execute when you call a method.

Spring Data works with interfaces in a different way than what you would do in a "normal" Java program. It looks at your repository interface, and then automatically generates a class that implements the interface when you run the program. When you call methods on the repository interface, what's actually executed is the code in that automatically generated class.

You never get to see the actual class, because it's generated dynamically, when you run the program - it doesn't yet exist when you write and compile the code.

This way of working is very powerful, and it's what makes Spring Data so nice to work with. You don't have to write all the tedious code for working with the database yourself - you only have to define an interface which specifies what exactly you want to get out of the database, and Spring Data will automatically generate all the code for you.

Sign up to request clarification or add additional context in comments.

Comments

3

It is functionality provided by Spring Data. Under the hood, Spring will determine which database you are trying to use. Say you are using the SQL database PostgreSQL. Spring determines it should use the appropriate interface JpaRepository. Then Spring Data JPA, one of the many Spring Data sub-modules, will provide the basic implementation for JpaRepository.

Spring is also able to dynamically provide implementations for any custom queries you've declared in CarRepository. However, for this to work, the declared methods need to follow specific naming conventions. For example, Spring is able to understand the method

List<Car> findByName(String name);

which will retrieve all Cars by parameter name, but not

List<Car> pleaseGiveAllCarsWithName(String name);

For the method naming conventions, please see the documentation.

It is because of these provided implementations by Spring that basic methods such as save but also custom defined queries such as findByName will work "out of the box".

3 Comments

Alright. So if I'd declare any additional method to CarRepository which is not overriding any method from CrudRepository interface, then I guess it won't be managed by all this Spring features? For example I'd add a method to a CarRepository: public String showCarBrand(Car car); so that it wouldn't know what to do with that?
@MaciejPapurzyński Yes indeed, you cannot add arbitrary methods to a repository interface, because Spring Data won't know how to generate an implementation for such methods. The method has to have a specific signature (see documentation) which Spring Data understands.
Updated my answer to include the custom query topic and documentation link by @Jesper

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.