JmixDataRepository - proposed improvements

I’m very happy with the support for spring-data-based repositories.
but I have the feeling some things are missing or weird.

1. Specific exception type for when the entity does not exist
I typically use the same convention in my repos. Return an optional on findxxx and throw an exception on getxxx.

But the JmixDataRepository throws an IllegalStateException. Besides the fact that I think it is the wrong kind of exception. It is also too generic, introducing an EntityNotFoundException allows us to handle it better. Think 404 in rest layers.

IllegalStateException javadoc: Signals that a method has been invoked at an illegal or inappropriate time. In other words, the Java environment or Java application is not in an appropriate state for the requested operation.

2. Provide equivalent methods without fetch plan
Most of my repos are used in service layers where I’m perfectly fine with default lazy loading rules and do not want to specify fetch plans. All of the JmixDataReposity methods include a fetchplan.

(Yes I am aware the super interfaces declare a number of methods without fetch plans, but not all)

3. Support for io.jmix.core.Id
UPDATE: after some experimentation, I found out that it is in fact possible, please update documentation. Declare your repository as

@Repository
public interface MyEntityRepository extends JmixDataRepository<MyEntity, Id<MyEntity>> {
}

Outdated - just here for reference
I’m a big fan of type-safe IDs eg. Id<MyEntity>

JMmixDataRepository depends on spring repositories that expect a generic type for entity and key. The problem is that the ID class has an untyped key.

This means I cannot call any methods on a repository by passing in io.jmix.core.Id The only way of extracting the key and passing it in is by casting it to the correct key type :scream:

Since the repos are expanding datamanager, it makes sense to support the same mechanism.

eg.

public interface MyJmixDataRepository<T, ID> extends JmixDataRepository<T, ID> {
    default T getById(Id<T> id) {
        return findById((ID) EntityValues.getId(id)).orElseThrow(() -> new NotFoundException(id));
    }
}

4. Support for dynamic attributes addon
noticed this cause I have this in one my of current repos

    public <T extends BaseUuidEntity> T loadWithDynamicAttributes(Id<T> id) {
        return (T) dataManager.load(id).hint(DynAttrQueryHints.LOAD_DYN_ATTR, true).one();
    }

5. expose datamanager through a getDataManager method.
So we can implement additional methods as default methods in the same repo

1 Like

Hello Tom!

Thank you for your feedback and ideas, we will discuss them and do our best to implement.

As for now, I can comment some of them:

2. getById has been added in Jmix 2.0 With this method, as I can see, all methods introduced in JmixDataRepository are present without fetchPlan in super interfaces or JmixDataRepository itself :
изображение
If I miss something or you have any ideas which particular method signatures can be added, please let me know.

4. Annotation io.jmix.core.repository.QueryHints can be used in order to add any hint to data repository method (see example in jmix tests):

    @Override
    @QueryHints({@QueryHint(name = DynAttrQueryHints.LOAD_DYN_ATTR, value = "true")})
    Optional<User> findById(UUID uuid);

5. Issue has been created.

Best regards,
Dmitry

1 Like