Blazebit / blaze-persistence

Rich Criteria API for JPA providers
https://persistence.blazebit.com
Apache License 2.0
721 stars 84 forks source link

Error mapping Map<String, Integer> with JdbcTypeCode(JSON) #1849

Open SeaLife opened 8 months ago

SeaLife commented 8 months ago

Error mapping a Map<String, Integer> stored as JSON using EntityViews

So my Entity has a Map defined like this:


    @JdbcTypeCode(SqlTypes.JSON)
    private Map<String, Integer> inventory;

I tried to return this field in a EV. I tried no Annotation, i tried "MappingSingular" and i tried "Basic"-Annotation. With "MappingSingular" i get:

java: > oder ',' erwartet

(produced code looks like this):

    public AttributePath<T, Map<String java.lang.Integer>, Map<String java.lang.Integer>> inventory() {
        MethodSingularAttribute<CompanyAccessTokenPublicCompanyView, Map<String java.lang.Integer>> attribute = CompanyAccessTokenPublicViewCompanyAccessTokenPublicCompanyView_.inventory;
        return attribute == null ? getWrapped().<Map<String java.lang.Integer>>get("inventory") : getWrapped().get(attribute);
    }

Using no annotation or Basic-Annnotation results in a runtime error:

java.lang.IllegalArgumentException: There are error(s) in entity views!
The resolved possible types [java.util.Map] are not assignable to the given expression type 'java.util.Collection<java.lang.Integer>' of the mapping expression declared by the attribute inventory[de.alteravitarp.govnet.database.government.company.CompanyAccessTokenPublicView$CompanyAccessTokenPublicCompanyView.getInventory]!
    at com.blazebit.persistence.view.impl.EntityViewManagerImpl.<init>(EntityViewManagerImpl.java:285) ~[blaze-persistence-entity-view-impl-jakarta-1.6.10.jar:1.6.10]
    at com.blazebit.persistence.view.impl.EntityViewConfigurationImpl.createEntityViewManager(EntityViewConfigurationImpl.java:257) ~[blaze-persistence-entity-view-impl-jakarta-1.6.10.jar:1.6.10]
    at de.alteravitarp.govnet.config.blaze.BlazeConfiguration.createEntityViewManager(BlazeConfiguration.java:36) ~[classes/:na]
    at de.alteravitarp.govnet.config.blaze.BlazeConfiguration$$SpringCGLIB$$0.CGLIB$createEntityViewManager$1(<generated>) ~[classes/:na]
    at de.alteravitarp.govnet.config.blaze.BlazeConfiguration$$SpringCGLIB$$FastClass$$1.invoke(<generated>) ~[classes/:na]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:258) ~[spring-core-6.0.13.jar:6.0.13]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-6.0.13.jar:6.0.13]
    at de.alteravitarp.govnet.config.blaze.BlazeConfiguration$$SpringCGLIB$$0.createEntityViewManager(<generated>) ~[classes/:na]
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:139) ~[spring-beans-6.0.13.jar:6.0.13]
    ... 51 common frames omitted

Expected behavior

I expect the application to start up and run.

Steps to reproduce

  1. Use Spring Boot 3.1.5 + Spring Boot JPA + Spring Boot WebMVC
  2. Create a Entity with a Map<?, ?> and use "@JdbcTypeCode(SqlTypes.JSON)"
  3. Create a EV returning the Map
  4. Error

Environment

Version: 1.6.10 JPA-Provider: Hibernate 6.2.13-FINAL DBMS: MariaDB Application Server: Spring Boot 3.1.5

beikov commented 7 months ago

Hi and thanks for the report. The compilation error you are observing happens for the generated metamodel. As a workaround, you should be able to disable metamodel generation by e.g. excluding the blaze-persistence-entity-view-processor dependency. The runtime error is due to the fact that you did not annotate the entity view mapping with @MappingSingular, which is necesary: https://persistence.blazebit.com/documentation/1.6/entity-view/manual/en_US/index.html#singular-collection-type-mappings

SeaLife commented 7 months ago

Hi and thanks for the report. The compilation error you are observing happens for the generated metamodel. As a workaround, you should be able to disable metamodel generation by e.g. excluding the blaze-persistence-entity-view-processor dependency. The runtime error is due to the fact that you did not annotate the entity view mapping with @MappingSingular, which is necesary: https://persistence.blazebit.com/documentation/1.6/entity-view/manual/en_US/index.html#singular-collection-type-mappings

Hey, i stated above in my report, that i tried using @MappingSingular. We rescheduled the project involved with this issue so i dont have time to check excluding the dependency right now. :)

ilxqx commented 4 months ago

I encountered the same issue with:

@MappingSingular
    Map<String, Object> getInfo();

It will generate the wrong type: MethodSingularAttribute<PersonView, Map<StringObject>>, obviously missing a comma between String and Object in the generics of Map.

ilxqx commented 4 months ago

The version I am using is 1.6.11. Currently, the issue can be resolved by removing the blaze-persistence-entity-view-processor dependency, but then we lose the benefits of performance improvement in static typing brought by blaze-persistence-entity-view-processor.

beikov commented 4 months ago

It will generate the wrong type: MethodSingularAttribute<PersonView, Map>, obviously missing a comma between String and Object in the generics of Map.

Thanks for the details. That should be easy to fix then.

ilxqx commented 4 months ago

@beikov Thanks for your work, looking forward to it being fixed.