복붙노트

[SPRING] 리포지토리에서의 Spring 데이터 JPA 상속

SPRING

리포지토리에서의 Spring 데이터 JPA 상속

@MappedSuperClass 주석이있는 추상 클래스가 있습니다. 이 추상 클래스를 확장하는 약 15 개의 엔티티가 있습니다 (데이터베이스에 15 개의 해당 테이블이 있음). 15 개의 엔티티는 모두 추상 수퍼 클래스에서 상속 된 것과 동일한 속성을가집니다.

나는 추상 클래스를 위해 아래와 같은 저장소를 만들었다 :

@NoRepositoryBean
public interface AbstractRepository <T extends AbstractClass, E extends Serializable>
                                    extends PagingAndSortingRepository<T, Serializable> {
  .....some methods here
}

15 개의 엔티티 / 테이블은 일부 데이터 (15 개의 개별 장비에 관련된 데이터)를 저장합니다. 선택한 장비에 따라 해당 테이블의 데이터가 검색됩니다. 15 개의 구체적인 개체에 대해 15 개의 별도 저장소를 만들어야합니까? 아니면 추상 저장소 만 사용하여 선택한 장비에 대해 특정 엔터티를 가져올 수있는 방법이 있습니까? 특정 구체에 대해 저장소를 생성해야하는 경우 특정 장비 호출에 적합한 저장소를 얻는 방법은 무엇입니까? 테이블 이름과 저장소 클래스를 응용 프로그램 시작시 생성되는 맵에 저장하십시오.

해결법

  1. ==============================

    1.각 클래스에 대한 저장소를 만들어야합니다. 그러나 당신은 추상적으로 당신의 방법을 유지할 수 있습니다. 각 메소드에 @Query를 제공하고 SpeL (Spring Expression Language)을 사용하여 쿼리에 유형을 추가해야합니다.

    각 클래스에 대한 저장소를 만들어야합니다. 그러나 당신은 추상적으로 당신의 방법을 유지할 수 있습니다. 각 메소드에 @Query를 제공하고 SpeL (Spring Expression Language)을 사용하여 쿼리에 유형을 추가해야합니다.

    @NoRepositoryBean
    public interface AbstractRepository 
            extends CrudRepository<T extends AbstractEquipment,Long>{
    
     @Query("select e from #{#entityName} as e from equipment where e.name = equipmentName")
     T findEquipmentByName(String equipmentName);
    
    }
    

    다음과 같이 확장하십시오.

    @Transactional
    public interface SpecialEquipmentRepo extends AbstractRepository<SpecialEquipment,Long>{
    
    }
    
  2. ==============================

    2.다음 설정이 이상적입니다.

    다음 설정이 이상적입니다.

    @Entity
    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    public abstract class Equipment { ... }
    
    @Entity
    public class Crane extends Equipment {}
    
    @Entity
    public class Excavator extends Equipment {}
    
    public interface EquipmentRepository<T extends Equipment> extends CrudRepository<T> {}
    
    @Service
    public class SomeService {
      @Autowired
      private EquipmentRepository<Crane> craneRepository;
    
      @Autowired
      private EquipmentRepository<Excavator> excavatorRepository;
    }
    

    Github에서 샘플 프로젝트를 설정하여이를 실제로 보여줍니다. Maven 테스트를 다음 중 하나로 실행하면 설정이 예상대로 작동 함을 입증하는 테스트를 통과하게됩니다.

    mvn test -Dspring.profiles.active="default,eclipselink"
    
    mvn test -Dspring.profiles.active="default,openjpa"
    

    즉,이 설정은 Hibernate에서 작동하지 않을 것입니다. Hibernate는 내가 사용하는 것으로 의심되는 것입니다. Hibernate는 TABLE_PER_CLASS 상속이있는 자동 증가 식별자 열을 지원하지 않는다. 따라서 Hibernate로 위의 설정을 실행하려고하면 예외가 발생합니다. 위에 링크 된 샘플에서 다음을 실행하여 확인할 수 있습니다.

    mvn test -Dspring.profiles.active="default,hibernate"
    
  3. from https://stackoverflow.com/questions/43350397/spring-data-jpa-inheritance-in-repositories by cc-by-sa and MIT license