Home > Software design >  Spring Data JPA : How to use @PathVariable and JPQL
Spring Data JPA : How to use @PathVariable and JPQL

Time:02-24

I have two questions about Spring Data JPA.

1st: How to avoid @PathVariable mistakingly recognizing a part of url as a parameter?

The first one is the code about this question. When I try to access "/sample/insert/", the url is handled as "/sample/{id}/" and I get the error which says like " String 'insert' cannot convert to Integer".

How do I avoid this problem?

2nd: Can JPQL @Query return an instance? Please refer to the second code.

For now, the method insertInto(String name, String mail) returns int value: the number of Column affected. However, I would like to get the affected column itself as a return value. Can I do this ? Or, should I add another code in a method in a service class to realize that function?

@RestController
public class SampleController{
    
    @Autowired
    SampleService sampleService;
    
    @RequestMapping
    public String index(Model model){
       //omitted
    }
    
    @GetMapping("/sample/")
    public String getAllSample(Model model){
       //omitted
    }
    
    @GetMapping("/sample/{id}/")
    public String getSampleById(@PathVariable("id") Integer id, Model model){
        System.out.println("===================");
        System.out.println(">> accessed: /sample/{id} ");
        System.out.println("===================");
        return sampleService.getById(id).toString();
    }

    @RequestMapping("/sample/insert/")
    public int insert(Model model){
        System.out.println("===================");
        System.out.println(">> accessed: /sample/insert/ ");
        System.out.println("===================");
        return sampleService.create("NewName", "[email protected]");
    }
@Transactional
@Repository
public interface SampleRepository extends JpaRepository<Sample, Integer>{
    
    @Query("SELECT s FROM Sample s ")
    public List<Sample> showAll();
    
    @Query("SELECT s FROM Sample s WHERE id = :id")
    public Sample searchById(@Param("id") Integer id);
    
    @Modifying
    @Query(value = "INSERT INTO sample (name, mail) VALUES (?1, ?2)", nativeQuery = true)
    public int insertInto(@Param("name") String name, @Param("mail") String mail);
    
}

CodePudding user response:

The first error you have is having a controller with {id} the same as /sample/insert/, I suppose because you have /sample/{id}/ before, he can match the /sample/insert/ to the first controller. Not sure if you swapped between the two methods, But I think it won't work as well. As you are confusing spring on which method should work with.



    @RequestMapping("/sample/insert/")
    public int insert(Model model){
        System.out.println("===================");
        System.out.println(">> accessed: /sample/insert/ ");
        System.out.println("===================");
        return sampleService.create("NewName", "[email protected]");
    }

    @GetMapping("/sample/{id}/")
    public String getSampleById(@PathVariable("id") Integer id, Model model){
        System.out.println("===================");
        System.out.println(">> accessed: /sample/{id} ");
        System.out.println("===================");
        return sampleService.getById(id).toString();
    }

What you can do to avoid that is, changing to /sample/get/{id} will fix the issue for sure.

    @GetMapping("/sample/{id}/")
    public String getSampleById(@PathVariable("id") Integer id, Model model){
        System.out.println("===================");
        System.out.println(">> accessed: /sample/{id} ");
        System.out.println("===================");
        return sampleService.getById(id).toString();
    }

    @RequestMapping("/sample/insert/")
    public int insert(Model model){
        System.out.println("===================");
        System.out.println(">> accessed: /sample/insert/ ");
        System.out.println("===================");
        return sampleService.create("NewName", "[email protected]");
    }

for the insertInto(String name, String mail), I believe you can do what you want, but first, you need to know what is the column type. then switch the method to return the type instead of int.

And if you can add more clarification about 2nd question, I will edit the answer to add more details.

CodePudding user response:

question one: enter image description here

their request url is same and request method both GET solution 1: change second request method turn to POST solution 2: change their request url, like this /smaple/{id}/info

CodePudding user response:

question 2: SampleRepository extends JpaRepository. JpaRepository defined many methods, include save method. you can code in sampleService
`@AutoWired
 SampleRepository sampleRepository;
 public Sample insert(String name, String email){
     Sample sample = new Sample();
     sample.setName(name);
     sample.setEmail(email);
     int result = this.sampleRepository.save(sample);
     if (result > 0){
       return sample;
     }
    //error
}`
  • Related