복붙노트

[SPRING] Spring 데이터 Mongodb 저장소는 상속을 올바르게 구현하지 않습니다.

SPRING

Spring 데이터 Mongodb 저장소는 상속을 올바르게 구현하지 않습니다.

하나의 MongoDB 컬렉션에서 두 개의 Java 클래스에 매핑되는 두 가지 유형의 엔티티가 있습니다.

@Document
public class Superclass { ... }

@Document(collection = "superclass")
public class Subclass extends Superclass { ... }

해당 엔티티에 대한 두 개의 리포지토리가 있습니다.

public interface SuperclassRepository extends MongoRepository<Superclass, String> {}
public interface SubclassRepository extends MongoRepository<Subclass, String> {}

MongoRepositories는 엔티티의 상속을 올바르게 처리하지 않습니다. 모든 하위 클래스 객체 (예 : SubclassRepository.findAll ())를 쿼리하는 동안 결과 집합에는 하위 클래스의 일부인 필드에 대해 Null 값을 사용하여 인스턴스화 (또는 적어도 인스턴스화를 시도했지만)되었지만 그렇지 않은 수퍼 클래스의 일부.

SuperclassRepository가 Superclass 및 Subclass 객체를 반환해야하는 반면 SubclassRepository는 Subclass 객체 만 반환해야하는 결과가 예상됩니다. Spring Data JPA에서 이런 식으로 작동합니다.

누구든지이 버그가 발생하여이를 해결하는 방법에 대한 해결책이 있습니까?

해결법

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

    1.나는 같은 문제를 겪는다.

    나는 같은 문제를 겪는다.

    소스 코드를 살펴보면 놀라 울 정도로 구현되지 않은 것 같습니다. Collection 이름과 엔티티 클래스를 추가하지만 _class 속성의 마지막 쿼리에는 삽입되지 않습니다. 그리고 그것을 살펴본 후 Mongo가 SuperClass에서 파생 된 SubClass1 또는 Subclass2를 어떻게 알게되는지 깨달았습니다. 그래서 SimpleMongoRepository 클래스를 재정의하고 기본 SimpleMongoRepository 대신 클래스를 저장하는 자체 공장을 만듭니다.

    여기에 내가 뭘 추가 :

    public MySimpleMongoRepository(MongoEntityInformation<T, ID> metadata, MongoOperations mongoOperations) {
    
        Assert.notNull(mongoOperations);
        Assert.notNull(metadata);
    
        this.entityInformation = metadata;
        this.mongoOperations = mongoOperations;
        Reflections reflections = new Reflections("com.cre8techlabs.entity");
        Set<String> subTypes = reflections.getSubTypesOf(entityInformation.getJavaType()).stream().map(Class::getName).collect(Collectors.toSet());
        subTypes.add(entityInformation.getJavaType().getName());
        this.baseClassQuery = Criteria.where("_class").in(subTypes.toArray());
    }
    

    여기에 find의 구현 예제가 있습니다.

    public T findOne(ID id) {
        Assert.notNull(id, "The given id must not be null!");
        Query q = getIdQuery(id).addCriteria(baseClassQuery);
    
        return mongoOperations.findOne(q, entityInformation.getJavaType(), entityInformation.getCollectionName());
    }
    

    그것은 저를 위해 작동합니다, 나는 조금 더 오래 걸릴 것을 두려워합니다.

  2. from https://stackoverflow.com/questions/28025710/spring-data-mongodb-repositories-dont-implement-inheritance-correctly by cc-by-sa and MIT license