0

I'm developing an application with Spring Data MongoDB. I use a base entity that serves as a superclass of all entities. Each entity therefore inherits from the base entity and has a @Document annotation with the desired collection name. Unfortunately, the class name of the base entity is always used as the collection name. When I run the following test, a collection "baseEntity" is created and the PersonEntity is saved there:

@Getter
@Setter
@EqualsAndHashCode
@SuperBuilder
@AllArgsConstructor
@NoArgsConstructor
public abstract class BaseEntity {

    @Id
    @Indexed(unique = true)
    @Field("_id")
    protected ObjectId id;

    @LastModifiedDate
    protected Date lastModified;

    @Version
    protected int version;
}

@Document(collection = "person")
@Getter
@Setter
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
public class PersonEntity extends BaseEntity {

    private String salutation;
    private String firstName;
    private String lastName;
}

public interface SaveDAO<T extends BaseEntity> extends MongoRepository<T, ObjectId> {

    @Override
    public <S extends T> S save(S entity);
}

@SpringBootTest
class SaveDAOTest {

    @Autowired
    private SaveDAO<PersonEntity> saveDao;

    @Test
    void testCreateEntity() {
        PersonEntity entity = new PersonEntity();
        saveDao.save(entity);
        // TODO assert
    }
}

I have already looked at various examples on the Internet and copied some code to try out (e.g. @Document also in the BaseEntity). Also, I have already tried to debug the Spring Data code. I noticed the following: in SimpleMongoRepository.save(...) "baseEntity" is returned when entityInformation.getCollectionName() is called. However, I didn't get much further or found any more useful information.

Edit: I just replaced the SaveDAO extends MongoRepository<T, ObjectId> with SaveDAO extends MongoRepository<PersonEntity, ObjectId>. Then the correct collection is created and used. So apparently it's because of my generic repository. Is there any solution to this (other than creating a separate repository for each entity)?

1
  • beside the answer to the question: is there a reason you don't want to have multiple repository interfaces? Commented Apr 10, 2024 at 14:24

1 Answer 1

0

The repository interfaces are meant to work with the actual domain object. So in your case, you need to define one repository per domain object.

This also has some performance benefits because the mapping to the domain object is stable.

If you have common methods, you can still create your intermediate repository interface, annotate it with @NoRepositoryBean and then create your domain-specific repository interfaces using this intermediate one.

So for your example, directly using MongoRepository:

public class BaseEntity {

}

public class PersonEntity extends BaseEntity {
}

public class VIPEntity extends BaseEntity {
}

public interface PersonDao implements MongoRepository<PersonEntity, ObjectId>

public interface PersonDao implements MongoRepository<VIPEntity, ObjectId>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.