QueryDsl ignoring predicate when using another #Query annotation - java

I have a repository looking like this (with other CRUD methods stripped)
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.StringPath;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.data.querydsl.binding.QuerydslBinderCustomizer;
import org.springframework.data.querydsl.binding.QuerydslBindings;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.lang.NonNull;
import org.springframework.security.access.prepost.PreAuthorize;
import java.util.Optional;
import java.util.UUID;
#PreAuthorize("hasRole('" + Constants.ROLE_USER + "')")
public interface ProjectRepository extends CrudRepository<Project, UUID>, QuerydslPredicateExecutor<Project>, QuerydslBinderCustomizer<QProject> {
#Override
default void customize(#NonNull QuerydslBindings bindings, #NonNull QProject root) {
bindings.bind(String.class).first(
(StringPath path, String value) -> path.containsIgnoreCase(value));
bindings.including(root.name);
bindings.including(root.description);
}
#Override
#Query("select p from Project p left join p.roles r left join r.account a where ?#{principal.username} = a.username")
#NonNull
Page<Project> findAll(#NonNull Predicate predicate, #NonNull Pageable pageable);
}
As you can see I have a #Query annotation that limits the response of findAll based on who the user is. This causes the Predicate to be ignored entirely. So if I search for anything, it still returns all objects the user has access to. If I remove the #Query annotation then the searching works correctly. But of course I want my security to be applied. Is this a bug in QueryDsl? Or simply a limitation? How could I make this work?

Related

Using record classes with #RequestBean in Micronaut

I am attempting to use Java records with #Valid and #RequestBean in Micronaut and am running into the following compilation error:
/Users/user/IdeaProjects/record_test/src/main/java/com/example/ReadController.java:16:28
java: Parameter of Primary Constructor (or #Creator Method) [id] for type [com.example.ReadBean] has one of #Bindable annotations. This is not supported.
Note1: Primary constructor is a constructor that have parameters or is annotated with #Creator.
Note2: In case you have multiple #Creator constructors, first is used as primary constructor.
My classes are as follows:
ReadBean.java:
package com.example;
import io.micronaut.core.annotation.Introspected;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.annotation.PathVariable;
import javax.validation.constraints.Positive;
#Introspected
public record ReadBean(HttpRequest<?> httpRequest, #PathVariable #Nullable #Positive Integer id) {
}
ReadController.java:
package com.example;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.Produces;
import io.micronaut.http.annotation.RequestBean;
import javax.validation.Valid;
#Controller("/api/read")
public class ReadController {
#Get
#Produces(MediaType.APPLICATION_JSON)
public HttpResponse<?> read(#Valid #RequestBean ReadBean bean) {
return HttpResponse.ok(bean);
} //read
}
This error appears to be due to my use of #PathVariable. I can get around this error by explicitly declaring the canonical constructor in my record:
package com.example;
import io.micronaut.core.annotation.Introspected;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.annotation.PathVariable;
import javax.validation.constraints.Positive;
#Introspected
public record ReadBean(HttpRequest<?> httpRequest, #PathVariable #Nullable #Positive Integer id) {
public ReadBean(HttpRequest<?> httpRequest, Integer id) {
this.httpRequest = httpRequest;
this.id = id;
} //ReadBean
}
Is there any cleaner way to get around this? I recall that annotations on record components are propagated to the associated fields, constructors, etc. It would just be nice to not have to declare the constructor explicitly.
Thanks!

Why this Jpa Query is not working when i use count inside query it is not working?

**please help i have placed hidden inside package and import something else is there please mind the change **
package hidden;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import hidden;
public interface SubscriberIdDetailsRepository extends JpaRepository<SubscriberIdDetails, Integer> {
#Query("Select count(distinct s.msisdn) from subscriber_details s where s.subscriber_details_id in (select d.subscriber_details_id from subscriber_id_details d where d.UPPER(REGEXP_REPLACE(id_number,'[^[:alnum:]'' '']', ''))=:idNumber")
Integer countByidNumber( #Param("idNumber") String idNumber);
}
Your query is calling REGEXP_REPLACE, which is a database-specific string function. It won't run as pure JPQL, so you will have to pass nativeQuery=true to the end of #Query to mark it as a native query.
public interface SubscriberIdDetailsRepository extends JpaRepository<SubscriberIdDetails, Integer> {
#Query(value = "SELECT COUNT(DISTINCT s.msisdn) FROM subscriber_details s WHERE s.subscriber_details_id IN (SELECT d.subscriber_details_id FROM subscriber_id_details d WHERE d.UPPER(REGEXP_REPLACE(id_number,'[^[:alnum:]'' '']', '')) = :idNumber",
nativeQuery = true
)
Integer countByidNumber(#Param("idNumber") String idNumber);
}

Can i do two jpa queries in one?

Im devloping a crud application in spring-boot and i was wondering if i can do these two queries and methods in one:
package com.celulaweb.crud.repository;
import com.celulaweb.crud.domain.Cidade;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
#Repository
public interface CidadeRepository extends JpaRepository<Cidade, Long> {
#Query("select c from Cidade c where c.estado is null or c.estado = :estado")
Page<Cidade> listarPorEstado(#Param("estado") String estado, Pageable pageable);
#Query("select c from Cidade c where c.nome is null or c.nome like :nome")
Page<Cidade> listarPorNomeTendo(#Param("nome") String nome, Pageable pageable);
}
These are queries from org.springframework.data.jpa.repository.Query
How can i merge these two?
If you have the same Pageable on this methods try this
#Query("""
select c from Cidade c
where (c.estado is null or (c.estado = :estado))
and (c.nome is null or (c.nome like :nome))
"""
)
Page<Cidade> listarEntries(
#Param("estado") estado: String,
#Param("nome") nome: String,
pageable: Pageable
)

can i retrieve data from another collection using MongoRepository?

i have a class called "Invoice" and a MongoRepository
and what i want is to extract from my mongo database all validated invoices (those created in a given time range)
so here is my mongo repository :
import java.util.Date;
import java.util.List;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import Invoices.Invoice;
#Repository
public interface InvoiceRepositoryMongo extends MongoRepository<Invoice,Integer>{
#Query("db.invoices_bis.find({createdAt : {$gte : new ISODate('2013-04-30T17:24:16.000+00:00') , $lte : new ISODate('2013-05-30T17:24:16.000+00:00')}})")
List<Document> testrequete(Date start, Date ed);
}
dont pay too much attention to the query it is just for testing , but the problem is when i run this , i have this error :
nested exception is org.springframework.data.mapping.PropertyReferenceException: No property testrequete found for type Invoice!
i think the problem is that the method return a list of but i'm not sure
thanks !
i think te problem is that your Entity calls Invoice,
MongoRepository<Invoice,Integer>
so the result should be something like :
List<Invoice> testrequete(Date start, Date ed);

Spring JPA Repository Return Object

I'm new in Spring. I want to create a repository that return Page of object array like this:
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
public interface A extends JpaRepository<Object, Long> {
#Query("SELECT a, b FROM EntityA a FULL OUTER JOIN EntityB b ON "
+ "a.id = b.id")
Page<Object[]> findAll(Pageable pageable);
}
But I get:
nested exception is java.lang.IllegalArgumentException: Not an managed type: class java.lang.Object
Thank you

Categories

Resources