Ranjan Kumar
Ranjan Kumar

Reputation: 103

Dynamically pick the Spring Data JPA Repository

I am new to the concept of type casting and Spring in Java.

I have below entities:

@MappedSuperclass
public class Fish {}

@Entity
public class Whale extends Fish{
  // There is no other property here..
}

@Entity
public class Shark extends Fish{
  // There is no other property here..
}

I have created corresponding repositories for these entity:

public interface WhaleRepository extends CrudRepository<Whale, String> {}

public interface SharkRepository extends CrudRepository<Whale, String> {}

I have a single controller where depending on the endpoint I want to save the data ..

@RestController
public class FishController {

    @ResponseBody
    @RequestMapping(value = "{fish-type}")
    public ResponseEntity<Long> create(@PathVariable("fish-type") String fishType, @RequestBody Fish fish){
        if(fishType.equals("whale"}{
           // Error: The method save(S) in the type CrudRepository<Whale,Long> is not applicable for the arguments (Fish)
           new WhaleRepository().save(fish); 
        }
        else if(fishType.equals("shark"}{
           // Error: The method save(S) in the type CrudRepository<Shark,Long> is not applicable for the arguments (Fish)
           new SharkRepository().save(fish);
        }
    }
}

Is there a way by which I can dynamically pick the repository and persist the data.

Upvotes: 0

Views: 1455

Answers (1)

İsmail Y.
İsmail Y.

Reputation: 3965

Yes you can.

Firstly, you have to create a abstract entity and repository.

Secondly, you need to use inheritance in Jackson to send generic entity in request.

For example, something like this:

FishRepository class:

public interface FishRepository extends JpaRepository<Fish, Long> {}

Fish class:

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "fishType")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Whale.class, name = "whale"),
        @JsonSubTypes.Type(value = Shark.class, name = "shark")
})
@MappedSuperclass
public abstract class Fish {

    @Id
    private Long id;

    public Fish() {
    }

    // getter/setter ..
}

Controller class:

@PostMapping(value = "/fish")
public String create(@RequestBody Fish fish) {
    ...
    fishRepository.save(fish);
    ...
}

Now you need to send the fishType inside your request. E.g:

{
    ...,
    "fishType": "shark"
}

References:

Spring @RequestBody inheritance

Spring Data Rest Repository with abstract class / inheritance

Upvotes: 0

Related Questions