Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected value type querying for Long #110

Open
jamoros opened this issue Jul 17, 2023 · 8 comments
Open

Unexpected value type querying for Long #110

jamoros opened this issue Jul 17, 2023 · 8 comments

Comments

@jamoros
Copy link

jamoros commented Jul 17, 2023

Greetings! I am using the rsql-jpa-spring-boot-starter with spring boot 3. So far all my queries work with no issues, but now I am trying to do something as simple as

query = "id==1";
repository.findAll(RSQLJPASupport.toSpecification(query));

And I get the following error:

java.lang.AssertionError: Unexpected value type (expected : java.lang.Long) : 1 (java.lang.String)
	at org.hibernate.sql.exec.internal.JdbcParameterBindingImpl.<init>(JdbcParameterBindingImpl.java:23)
	at org.hibernate.sql.exec.spi.JdbcParameterBindings.createAndAddBinding(JdbcParameterBindings.java:97)
	at org.hibernate.type.BasicType.forEachDisassembledJdbcValue(BasicType.java:135)
	at org.hibernate.metamodel.mapping.Bindable.forEachJdbcValue(Bindable.java:197)

I've read all the docs in the read me and tried other ways such as >1=;<=1 but anything I do with a number for an ID I get the above error.

EDIT
I believe I figured out the issue, my entity extends an AbstractEntity that holds the ID value. So the classes are as follow:

@MappedSuperclass
@NoArgsConstructor
@Getter
@Setter
@Accessors(chain = true)
@EqualsAndHashCode
public class AbstractEntity<T> {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected T id;

    @Version
    @Column(columnDefinition = "int default 0")
    protected Integer version = 0;

}

The entity I am querying for is this:

@Entity
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@RequiredArgsConstructor(staticName = "of")
@Accessors(chain = true)
public class Instance extends AbstractEntity<Long> {

    @NotNull
    @NonNull
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @JoinColumn(foreignKey = @ForeignKey(name = "FK_definition_id"))
    private Definition Definition;

}

I am using Lombok's @DaTa for all getters and setters. The way I have it setup returns me the error, however if I do not extend AbstractEntity and put the ID in my Instance class, the query "id==1" actually does work.

Is there a way a fix can be put into this? Or do I have to have the ID in every entity I wish to query with RSQL? I'll continue testing on my end and see if I can find any other solutions.

Thank you!

@perplexhub
Copy link
Owner

Could you try not using generic type as ID field?

@jamoros
Copy link
Author

jamoros commented Jul 27, 2023

That worked.

The query:

String query = "instance.id==1";

I created a new parent class

@MappedSuperclass
@NoArgsConstructor
@Getter
@Setter
@Accessors(chain = true)
@EqualsAndHashCode
public class NonGenericAbstractEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Version
    @Column(columnDefinition = "int default 0")
    protected Integer version = 0;

}

And I extended it

@Entity
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@RequiredArgsConstructor(staticName = "of")
@Accessors(chain = true)
public class Instance extends NonGenericAbstractEntity {

    @NotNull
    @NonNull
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @JoinColumn(foreignKey = @ForeignKey(name = "FK_definition_id"))
    private Definition Definition;

}

So it's clear Lombok is not the issue but using a generic in the parent class. I suppose there is no work around for this and I will have to use the non generic type for ID?

@perplexhub
Copy link
Owner

Not sure, the exception was raised in hibernate. You may try to print out the generated SQL and parameters to check further.

@jamoros
Copy link
Author

jamoros commented Jul 27, 2023

I think I am fine with removing the generic for the concrete Long for the ID, but I was wondering if there was something to fix it. This is the logging with the generated sql and the exception:

Hibernate: 
    select
        t1_0.id,
        t1_0.instance_id,
        t1_0.version 
    from
        instance t1_0 
    where
        t1_0.id=?

Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 6.635 s <<< FAILURE! -  Time elapsed: 0.769 s  <<< 
FAILURE!
java.lang.AssertionError: Unexpected value type (expected : java.lang.Long) : 1 (java.lang.String)
	at org.hibernate.sql.exec.internal.JdbcParameterBindingImpl.<init>(JdbcParameterBindingImpl.java:23)
	at org.hibernate.sql.exec.spi.JdbcParameterBindings.createAndAddBinding(JdbcParameterBindings.java:97)
	at org.hibernate.type.BasicType.forEachDisassembledJdbcValue(BasicType.java:135)
	at org.hibernate.metamodel.mapping.Bindable.forEachJdbcValue(Bindable.java:197)
	at org.hibernate.sql.exec.spi.JdbcParameterBindings.registerParametersForEachJdbcValue(JdbcParameterBindings.java:78)
	at org.hibernate.sql.exec.spi.JdbcParameterBindings.registerParametersForEachJdbcValue(JdbcParameterBindings.java:69)
	at org.hibernate.query.sqm.internal.SqmUtil.createValueBindings(SqmUtil.java:409)
	at org.hibernate.query.sqm.internal.SqmUtil.createJdbcParameterBindings(SqmUtil.java:338)
	at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.buildCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:358)
	at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:268)
	at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:244)
	at org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:518)
	at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:367)
	at org.hibernate.query.Query.getResultList(Query.java:119)
	at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:440)

Thanks!

@perplexhub
Copy link
Owner

Do you see this message in the debug log?
convert(source:1,targetType:Class java.lang.String)

@jamoros
Copy link
Author

jamoros commented Jul 27, 2023

It's Object instead of String, here is the log (with some previous lines)

i.github.perplexhub.rsql.RSQLJPASupport  : toSpecification(Instance.id==1,distinct:false,propertyPathMapper:null,customPredicates:0,joinHints:null,propertyWhitelist:null,propertyBlacklist:null)
i.g.p.rsql.RSQLJPAPredicateConverter     : visit(node:Instance.id=='1',root:com.workflow.InstanceVariable)
i.g.perplexhub.rsql.RSQLVisitorBase      : Found managed type [class com.workflow.InstanceVariable] in EntityManager [jpaSharedEM_AWC_entityManagerFactory]
i.g.perplexhub.rsql.RSQLVisitorBase      : Found managed type [class com.workflow.Instance] in EntityManager [jpaSharedEM_AWC_entityManagerFactory]
i.g.p.rsql.RSQLJPAPredicateConverter     : Create property path for type [com.workflow.Instance] property [Instance]
i.g.p.rsql.RSQLJPAPredicateConverter     : Create property path for type [com.workflow.Instance] property [id]
i.g.perplexhub.rsql.RSQLVisitorBase      : accessControl(type:class com.workflow.Instance,name:id)
i.g.perplexhub.rsql.RSQLVisitorBase      : convert(source:1,targetType:class java.lang.Object)
o.h.q.sqm.sql.BaseSqmToSqlAstConverter   : Determining mapping-model type for SqmParameter : org.hibernate.query.sqm.tree.expression.SqmJpaCriteriaParameterWrapper@5a0b550a

Time elapsed: 0.698 s  <<< FAILURE!
java.lang.AssertionError: Unexpected value type (expected : java.lang.Long) : 1 (java.lang.String)

@perplexhub
Copy link
Owner

perplexhub commented Jul 27, 2023

It looks like attribute.getJavaType() in RSQLJPAPredicateConverter returns Object instead of Long for your entity class. Could you set break point on line 198 to see any hints?

@jamoros
Copy link
Author

jamoros commented Jul 27, 2023

You're correct, that it's returning Object instead of Long. I put a breakpoint however I cannot find any reasons why this would be. Is there any additional info I can provide from the breakpoint? I attached a screenshot of the attribute with some of it's values.

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants