Единый репозиторий для нескольких объектов с @DiscriminatorValue - PullRequest
1 голос
/ 02 мая 2019

У меня есть несколько сущностей, совместно использующих одну и ту же таблицу базы данных с @DiscriminatorValue с одним базовым классом:

@Entity(name = "base_details")
@DiscriminatorColumn(name = "type")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Getter
@Setter
public abstract class BaseDetails {

    @Id
    @Column(name = "identifier")
    private String identifier;

    @Column(name = "item_type")
    @Enumerated(EnumType.STRING)
    private Type type;

}

@Entity
@DiscriminatorValue("ONE")
@Getter
@Setter
public class FirstDetails extends BaseDetails {
...
}

@Entity
@DiscriminatorValue("TWO")
@Getter
@Setter
public class SecondDetails extends BaseDetails {
...
}

Это работает нормально, но я сталкиваюсь с проблемой слишком большого количества отдельных репозиториев:

@Repository
public interface OneDetailsRepository extends JpaRepository<OneDetails, String> { ... }

и т. Д.

Есть ли способ, как иметь один репозиторий (например, BaseDetailsRepository), который будет работать со всеми производными сущностями?

РЕДАКТИРОВАТЬ: Кто яищу что-то вроде этого:

@Repository
public interface BaseDetailsRepository extends JpaRepository<? extends BaseDetails, String> { 
    OneDetails findOne(String identifier);
    SecondDetails findOne(String identifier);
}

Ответы [ 2 ]

1 голос
/ 02 мая 2019

Вы можете сделать следующее:

Репозиторий: BaseDetailsRepo.java

@Repository
public interface BaseDetailsRepo extends JpaRepository<BaseDetails, String>{
//make the return according to you ..it shouldn't be list....

    @Query("FROM SecondDetails AS bd WHERE bd.identifier=:identifier")
    public List<SecondDetails> getSecondDetailsByIdentifier(@Param("identifier") String identifier);

    @Query("FROM FirstDetails AS bd WHERE bd.identifier=:identifier")
    public List<FirstDetails> getFirstDetailsByIdentifier(@Param("identifier") String identifier);          
}

Контроллер: DemoController.java

@Controller
public class DemoController {

    @Autowired
    private BaseDetailsRepo baseDetailsRepo;


    @GetMapping(value="/test")
    public ResponseEntity test(){

        FirstDetails fd = new FirstDetails();
        fd.setIdentifier("fd1-demo");

        FirstDetails fd1 = new FirstDetails();
        fd1.setIdentifier("fd2-demo");


        SecondDetails sd = new SecondDetails();
        sd.setIdentifier("sd1-demo");
        baseDetailsRepo.save(fd);
        baseDetailsRepo.save(fd1);
        baseDetailsRepo.save(sd);

        return new ResponseEntity("Success",HttpStatus.OK);
    }


    @GetMapping(value="/test/second/{id}")
    public ResponseEntity getSecondDetails(@PathVariable String id){
        return new ResponseEntity(baseDetailsRepo.getSecondDetailsByIdentifier(id),HttpStatus.OK);
    }


    @GetMapping(value="/test/first/{id}")
    public ResponseEntity getFirstDetails(@PathVariable String id){
        return new ResponseEntity(baseDetailsRepo.getFirstDetailsByIdentifier(id),HttpStatus.OK);
    }
}

Вывод

Test

1 голос
/ 02 мая 2019
@NoRepositoryBean    // Read only repository
public interface BaseDetailsRepository<T extends BaseDetails> 
extends JpaRepository<T, String> {  
 T findOne(String identifier);
 T findOne(Long id);
 Iterable<T> findAll();
 Iterable<T> findAll(Sort sort);
 Page<T> findAll(Pageable pageable);
}

, и вы также можете иметь три репозитория для каждой сущности:

 @Transactional
public interface BaseRepository extends BaseDetailsRepository<BaseDetails> {   }
@Transactional
public interface FirstDetailsRepository extends BaseDetailsRepository<BaseDetails>,JpaRepository<T extends BaseDetails, String>{ }

@Transactional
public interface SecondDetailsRepository extends BaseDetailsRepository<BaseDetails>,JpaRepository<T extends BaseDetails, String> {  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...