Skip to content

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

Open
@spring-projects-issues

Description

@spring-projects-issues

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions