Spring boot Issue IllegalArgumentException when using Order By in Repository - spring

im having an annoying issue where I cant seem to find a solution for.
Im currently implementing a way to read only the top 500 Entries ordered by Date. If I dont enter the Order By, Spring boot delivers the top 500 which is fine, but as soon as I include the Order By Option I get this Error:
Caused by: java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List com.sma.db.repositories.LogRepository.findTop500ByOrderBylogsLogTimeDesc()! No property orderBylogsLogTimeDesc found for type LogEntity!
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:96) ~[spring-data-jpa-2.3.5.RELEASE.jar:2.3.5.RELEASE]
As it seems, Spring boot includes the Order by and and looks for a property named orderbylogsLogTimeDesc . What I also dont understand is, why order is written in lower cases.
Does anyone know a solution for this? It is really annoying and I cant seem to find a solution :(
Repository:
#Repository
public interface LogRepository extends JpaRepository<LogEntity, Long>{
// List<FeedEntity> deleteByfeedTimestamp(Date feed_timestamp);
List<LogEntity>findTop500ByOrderBylogsLogTimeDesc();
}
Entity:
#Column(name = "logs_logtime")
private Date logsLogTime;
public Date getLogsLogTime() {
return logsLogTime;
}
public void setLogsLogTime(Date logsLogTime) {
this.logsLogTime = logsLogTime;
}
Service:
#Service
public class LogService {
#Autowired
private LogRepository repo;
public List<LogEntity> getLogs() {
return repo.findTop500ByOrderBylogsLogTimeDesc();
}
Ive found the solution in the end: I had to write LogsLogTime instead of logsLogTime... . It works now :) Thanks!

Maybe you have to specify the field twice, have you tried:
List<LogEntity>findTop500ByLogsLogTimeOrderByLogsLogTimeDesc();

You guys gave me an idea. I actually found the Issue! When i typed LogsLogTime it worked as in:
findTop500ByOrderByLogsLogTimeDesc

Related

Returning only the first 10 record - Redis OM

I’m using Redis OM for spring boot, I am having trouble querying objects because it only returns the first 10 records.
Repository Class:
public interface RedisBillerRepository extends RedisDocumentRepository<Biller, Long> {
List<Biller> findByClientIds(String clientId);
}
Is there a way to return ALL the objects with the specific clientId? Not the first 10 only.
The only way which i found was with the interface Page. For example your Repository would look like this:
public interface RedisBillerRepository extends RedisDocumentRepository<Biller, Long> {
Page<Biller> findByClientIds(String clientId, Pageable pageable);
}
And your class could look like this
public class BillerService {
#Autowired
RedisBillerRepository redisBillerRepository;
public List<Biller> getAllClientsById(String clientId){
Pageable pageRequest = PageRequest.of(0, 500000);
Page<Biller> foundBillers = redisBillerRepository.findByClientIds(clientId, pageRequest);
List<Biller> billersAsList = foundBillers.getContent();
return billersAsList;
}
}
You have to set the limit for now.
I'm the author of the library... #member2 is correct. RediSearch currently has a default for the underlying FT.SEARCH (https://redis.io/commands/ft.search/) method of returning the first 10 records found. To override that, the only way to do so currently is to use the Pagination constructs in Spring.
I will expose a configuration parameter in upcoming versions to set the MAX globally.

Injection of bean inside ClientHeadersFactory doesn't work

I'm building a Quarkus app which handles http requests with resteasy and calls another api with restclient and I need to propagate a header and add another one on the fly so I added a class that implements ClientHeadersFactory.
Here's the code:
#ApplicationScoped
public abstract class MicroServicesHeaderHandler implements ClientHeadersFactory {
#Inject
MicroServicesConfig config;
#Override
public MultivaluedMap<String, String> update(MultivaluedMap<String, String> incomingHeaders,
MultivaluedMap<String, String> clientOutgoingHeaders) {
// Will be merged with outgoing headers
return new MultivaluedHashMap<>() {{
put("Authorization", Collections.singletonList("Bearer " + config.getServices().get(getServiceName()).getAccessToken()));
put("passport", Collections.singletonList(incomingHeaders.getFirst("passport")));
}};
}
protected abstract String getServiceName();
My issue is that the injection of the config doesn't work. I tried both with #Inject and #Context, as mentioned in the javadoc of ClientHeadersFactory. I also tried to make the class non abstract but it doesn't change anything.
MicroServicesConfig is a #Startup bean because it needs to be initialized before Quarkus.run() is called, otherwise the hot reload doesn't work anymore, since it's required to handle requests.
Here's the code FYI:
#Getter
#Startup
#ApplicationScoped
public final class MicroServicesConfig {
private final Map<String, MicroService> services;
MicroServicesConfig(AKV akv, ABS abs) {
// some code to retrieve an encrypted file from a secure storage, decrypt it and initialize the map out of it
}
It appears to be an issue with ClientHeadersFactory because if I inject my bean in my main class (#QuarkusMain), it works. I'm then able to assign the map to a public static map that I can then access from my HeaderHandler with Application.myPublicStaticMap but that's ugly so I would really prefer to avoid that.
I've searched online and saw several people having the same issue but according to this blogpost, or this one, it should work as of Quarkus 1.3 and MicroProfile 3.3 (RestClient 1.4) and I'm using Quarkus 1.5.2.
Even the example in the second link doesn't work for me with the injection of UriInfo so the issue doesn't come from the bean I'm trying to inject.
I've been struggling with this for weeks and I'd really like to get rid of my workaround now.
I'm probably just missing something but it's driving me crazy.
Thanks in advance for your help.
This issue has finally been solved in Quarkus 1.8.

Reading multiple entity scan packages in spring boot application

I have Spring boot application
#SpringBootApplication
#EntityScan(basePackages = {"${scan.packages}"})
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
While reading multiple entity scan packages from one property separated by comma like below?
scan.packages=com.mycompany.model.package1 ,
com.mycompany.model.package2
I got this exception :
java.lang.IllegalArgumentException: Unknown entity:
com.mycompany.model.package2.Myclass
You can scan multiple Entity like this
#EntityScan(basePackages= {"scan.packages1","scan.packages2"})
This should work
#EntityScan(basePackages = {"#{'${scan.packages}'.split(',')}"})
According to the EntityScan annotation javadoc there are three ways to define the packages where to scan for entities:
value, alias for basePackages: #EntityScan( {"scan.packages1","scan.packages2"})
basePackages, alias for value: #EntityScan(basePackages= {"scan.packages1","scan.packages2"}).
basePackagesClasses, the type safe version: #EntityScan(basePackages=E.class}.Where E was a marker interface just to underline the Entities. Please see the code bellow. It could also be an annotation.
interface E {
}
#Entity
public class Glass implements E {
// Typical code to be added here
}
Or as an annotation:
#Retention(RetentionPolicy.RUNTIME)
#interface E {
}
#Entity
#E
public class Glass implements E {
// Typical code to be added here
}
From my perspective I would choose either using directly value or basePackageClasses. If I can something easier to read I would do that, and I think that is what value does, while the basePackageClasses introduces the added benefit of type safety and I can see multiple reasons to go for that. It all depends on the context.
I hit the same problem and posted an issue on the Spring Boot issue tracker about it.
The answer was that
... As shown by #25436, #EntityScan did support property solution in 2.3 so, if we decide to reinstate support, we might want to consider how to handle multi-value properties.
So it appears some Spring Boot version did support it, but then the support was dropped again... for more info, check the Spring Boot issue linked in the quote.
try this :
#EntityScan(basePackages= {"${scan.packages1","scan.packages2}"})

Spring rest API: saveAll

I see in CrudRepository interface there is a method "saveAll".
There is anyway to use it without doing any customization to the code passing in a POST request an array of json of the corresponding entity?
I can't figure out why all the other methods are mapped except this.
Thanks Mik
It will take a collection and persist. Its hard to answer your question without sample code or what you have done so far but this is how it works on some ExampleClient code.
Just ensure you have latest version on spring-data-jpa.
#Component
public class ExampleClient {
#Autowired
private EmployeeRepository repo;
public void run() {
List<Employee> employees = createEmployees();
System.out.println(" -- saving employees --");
System.out.println(employees);
repo.saveAll(employees);
.......
........

How can I name a #Service with multiple names in Spring?

I need something like:
#Named({"bean1", "bean2"})
#Service({"bean1", "bean2"})
Can someone help me?
Not directly, the way you have it. But it is possible by redefining an existing #Service (or #Component) as a #Bean with either a name or list of names, it is possible.
#Service("Service-A")
public class SampleService {
public String doSomething() { return "Foo"; }
}
#Configuration
public class SampleConfig {
#Bean(name = {"Service-B", "Service-C"})
public SampleService createMirroredService(#Autowired SampleService service) {
return service;
}
}
And now you have three instances of SampleService: Service-A (your #Service), Service-B, and Service-C. This works because you define one and just have the #Bean annotated method pass through the implementation, which has the effect of creating aliases. Make sure the configuration class is picked up in the scan and it should work fine.
Note: Although this works, and there are probably other solutions as well, I can't think of a case where I would need this. Perhaps if I'm integrating with a library that already exists that I can't change. But there doesn't strike me as a serious need for this, or else they would have made value on #Component an array.
Though I think #Todd answer is totally correct. It seems it has mislead some others to follow the idea. See Autowire Map with custom class and use aliases to get the correct object reference.
Therefore I would like to add an answer here to suggest one to use the below methodology instead.
#Configuration
public class SampleConfig {
#Bean(name = {"Service-A", "Service-B", "Service-C"})
public SampleService createMirroredService() {
return new SampleService();
}
}
This would be much cleaner than the above answer, though may not answer the question properly.

Resources