spring-projects / spring-projects/spring-data-commons

Querydsl web binding support can not bind ListPath query parameters [DATACMNS-1546]

Open
#1,933 5 comments 2 reactions 1 assignee View on GitHub

@odrotbohm is already working on this.

Since Dec 30, 2020.

type: bug
Dominant language
Java
Stars
838
Forks
730
PR merge metrics
No merged PRs in 30d

Description

XhstormR opened DATACMNS-1546 and commented

I have a Repository class like this:

@Repository
interface ContractRepository :
        BaseRepository<Contract, QContract, Long> {

    @JvmDefault
    override fun customize(bindings: QuerydslBindings, root: QContract) {
    }
}

BaseRepository inherits QuerydslPredicateExecutor and QuerydslBinderCustomizer, by the way this is kotlin code.

And i have a Project entity that contains a one-to-many relationship like this:

@Entity
@DynamicInsert
@DynamicUpdate
class Project(
        var startTime: LocalDateTime? = null,
        var deadline: LocalDateTime? = null,
        var finishTime: LocalDateTime? = null,
        var finish: Boolean = false
) : BaseSequenceEntity() {

    @OneToMany(mappedBy = "project", cascade = [CascadeType.PERSIST])
    var subsystems = mutableListOf<Subsystem>()
}

Now I have a binding like this, but I found it doesn't work, use only the most basic equals operator:

@Repository
interface ContractRepository :
        BaseRepository<Contract, QContract, Long> {

    @JvmDefault
    override fun customize(bindings: QuerydslBindings, root: QContract) {
        bindings.bind(root.project.subsystems.any().name).first { path, value ->
            println(111)
            path.contains(value)
        }
    }
}

After I send a request to the server, request like this:

http://127.0.0.1:8080/api/search/contract?page=0&size=10&sort=createdAt,desc&project.subsystems.name=ffff

Server output is:

2019-06-19 08:39:23.142  INFO 415552 --- [nio-8080-exec-4] c.x.e.a.c.handler.RequestInterceptor     : GET [uri=/api/search/contract;client=127.0.0.1;session=039EB2C355C8CE222CC9FEC789F672DB;user=1@a.com]
2019-06-19 08:39:23.145 DEBUG 415552 --- [nio-8080-exec-4] org.hibernate.SQL                        : /* select contract
from Contract contract
where exists (select 1
from contract.project.subsystems as contract_project_subsystems_0
where contract_project_subsystems_0.name = ?1)
order by contract.createdAt desc */ select contract0_.id as id1_5_, contract0_.created_at as created_2_5_, contract0_.created_by_id as created_9_5_, contract0_.updated_at as updated_3_5_, contract0_.updated_by_id as updated10_5_, contract0_.optlock as optlock4_5_, contract0_.company_id as company11_5_, contract0_.file_id as file_id12_5_, contract0_.finish_date as finish_d5_5_, contract0_.name as name6_5_, contract0_.start_date as start_da7_5_, contract0_.urgency as urgency8_5_ from erp_dev.contract contract0_ where exists (select 1 from erp_dev.project project1_ cross join erp_dev.subsystem subsystems2_ where contract0_.id=project1_.contract_id and project1_.id=subsystems2_.project_id and subsystems2_.name=?) order by contract0_.created_at desc limit ?

The main SQL is:

select contract
from Contract contract
where exists (select 1
from contract.project.subsystems as contract_project_subsystems_0
where contract_project_subsystems_0.name = ?1)
order by contract.createdAt desc

But I found that if my binding is like this, the binding will take effect:

@Repository
interface ContractRepository :
        BaseRepository<Contract, QContract, Long> {

    @JvmDefault
    override fun customize(bindings: QuerydslBindings, root: QContract) {
        bindings.bind(String::class.java).all(MultiValueBinding<StringPath, String> { path, values ->
            println(222)
            if (root.project.subsystems.any().name == path) Optional.of(path.contains(values.single()))
            else Optional.empty()
        })
    }
}

Server output is:

2019-06-19 08:42:19.862  INFO 416072 --- [nio-8080-exec-1] c.x.e.a.c.handler.RequestInterceptor     : GET [uri=/api/search/contract;client=127.0.0.1;session=820AB7D7035D193D33711DEEAF9486BD;user=1@a.com]
222
2019-06-19 08:42:19.865 DEBUG 416072 --- [nio-8080-exec-1] org.hibernate.SQL                        : /* select contract
from Contract contract
where exists (select 1
from contract.project.subsystems as contract_project_subsystems_0
where contract_project_subsystems_0.name like ?1 escape '!')
order by contract.createdAt desc */ select contract0_.id as id1_5_, contract0_.created_at as created_2_5_, contract0_.created_by_id as created_9_5_, contract0_.updated_at as updated_3_5_, contract0_.updated_by_id as updated10_5_, contract0_.optlock as optlock4_5_, contract0_.company_id as company11_5_, contract0_.file_id as file_id12_5_, contract0_.finish_date as finish_d5_5_, contract0_.name as name6_5_, contract0_.start_date as start_da7_5_, contract0_.urgency as urgency8_5_ from erp_dev.contract contract0_ where exists (select 1 from erp_dev.project project1_ cross join erp_dev.subsystem subsystems2_ where contract0_.id=project1_.contract_id and project1_.id=subsystems2_.project_id and (subsystems2_.name like ? escape '!')) order by contract0_.created_at desc limit ?

The main SQL is:

select contract
from Contract contract
where exists (select 1
from contract.project.subsystems as contract_project_subsystems_0
where contract_project_subsystems_0.name like ?1 escape '!')
order by contract.createdAt desc

1 votes, 4 watchers

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.