I would like to ues Pageable object in controller's method to eliminate the redundant page and size parameters. Just like the following:
#RequestMapping("/list")
public String list(Model model , Pageable pageable) {
logger.info("pageable = {}" , pageable);
// ... skipped
}
Instead of:
#RequestMapping("/list")
public String list(Model model , Integer page, Integer size) {
logger.info("page = {}, size = {}" , page, size);
// ... skipped
}
However, after adding the org.springframework.boot:spring-boot-starter-data-jpa dependency to my pom.xml, I've been always asked for setting up the 'entityManagerFactory' bean, which looks like something from the embedded hibernate dependency.
How can I use the Pageable obejct and get rid of the Spring Data things?
Pageable is part of the Spring Data Commons project -
and I've never seen it used outside of Spring Data.
That said... it may be possible, but you'd have to pull in the appropriate jar containing the Pageable class, without pulling in any of the Spring Boot Starter Data - * dependencies. If you add the starter, Spring boot is going to attempt to perform automatic datasource configuration, which it sounds like you do not want.
You could try to pull in the single dependency that contains that class (org.springframework.data:spring-data-commons i believe). You should then have access to the Pageable class without any autoconfiguration.
Try to use spring data JDBC. This would help you avoid the need to use JPA!
Here is a good source of information about jdbc: Github-Spring Data JDBC generic DAO implementation
Related
I'm migrating a legacy application from Spring-core 4 to Springboot 2.5.2.
The application is using spring-data-rest (SDR) alongside spring-data-mongodb to handle our entities.
The legacy code was overriding SDR configuration by extending the RepositoryRestMvcConfiguration and overriding the bean definition for persistentEntityJackson2Module to remove serializerModifier and deserializerModifier.
#EnableWebMvc
#EnableSpringDataWebSupport
#Configuration
class RepositoryConfiguration extends RepositoryRestMvcConfiguration {
...
...
#Bean
#Override
protected Module persistentEntityJackson2Module() {
// Remove existing Ser/DeserializerModifier because Spring data rest expect linked resources to be in href form. Our platform is not tailored for it yet
return ConverterHelper.configureSimpleModule((SimpleModule) super.persistentEntityJackson2Module())
.setDeserializerModifier(null)
.setSerializerModifier(null);
}
It was to avoid having to process DBRef as href link when posting entities, we pass the plain POJO instead of the href and we persist it manually before the entity.
Following the migration, there is no way to set the same overrided configuration but to avoid altering all our processes of creation we would like to keep passing the POJO even for DbRef.
I will add an exemple of what was working before :
We have the entity we want to persist :
public class EntityWithDbRefRelation {
....
#Valid
#CreateOnTheFly // Custom annotation to create the dbrefEntity before persisting the current entity
#DBRef
private MyDbRefEntity myDbRefEntity;
}
the DbRefEntity
public class MyDbRefEntity {
...
private String name;
}
and the JSON Post request we are doing:
POST base-api/entityWithDbRefRelations
{
...
"myDbRefEntity": {
"name": "My own dbRef entity"
}
}
In our database this request create our myDbRefEntity and then create the target entityWithDbRefRelation with a dbRef linked to the other entity.
Following the migration, the DBRef is never created because when deserializing the JSON into a PersistingEntity, the myDbRefEntity is ignored because it's expecting an href instead of a complex object.
I see 3 solutions :
Modify all our process to first create the DBRef through one request then create our entity with the link to the dbRef
Very costly as we have a lot of services creating entities through this backend
Compliant with SDR
Define our own rest mvc controllers to do operations, to ignore the SDR mapping machanism
Add AOP into the RepositoryRestMvcConfiguration around the persistentEntityJackson2Module to set le serializerModifier and deserializedModifier to null
I really prefer to avoid this solution as Springboot must have remove a way to configure it on purpose and it could break when migrating on newer version
Does anyone know a way to continue considering the property as a complex object instead of an href link except from my 3 previous points ?
Tell me if you need more information and thanks in advance for your help!
I read some articles conecerning clean architecture.
These articles say that business layer should not know how to solve domain knowledge directly. (only what to do)
PageRequest object is provided by spring framework.
And this object implements Pageable interface.
My question is...
Do i create the Pagerequest in business layer (service)
or inject it to the layer?
You said the PageRequest / Pageable object is provided by Spring, so - if you are using Spring MVC - I would expect something like the following on controller level:
#RequestMapping(method = ..., path = ..., produces = ...)
public ... readSomethingPaged(#PathVariable String ..., Pageable pageable) {
...
}
Then of course you have to pass this Pageable (created automagically by Spring using the request parameters page=...&size=...&sort=...) through your service layer down to the place you are getting the data from. Within Spring (Boot) a Spring Data JPA repository comes in handy. It accepts the Pageable created by the controller and returns the appropriate data.
Or what exactly do you mean with "Do i create the Pagerequest in business layer"?
If you really have to create your own PageRequest it has to be done before the repository is called, then imho not the service itself but the controller / a facade should be responsible for that.
In my Spring Boot application I use a following DTO with #RestController:
public abstract class ComparableQuery extends BaseQuery {
private final Object value;
...
}
Everything works fine but when I use Spring RestTemplate and pass java.util.Date as ComparableQuery.value I see that Jackson serialize the date object into the following "magic" number:
"value":1009836000000
Right now I don't understand how the date object serialized into the 1009836000000 number representation and how to emulate it when I use for example AngularJS as a client of my back-end API. Please advise.
This is a very similar problem as described in this answer about null handling with jackson and spring boot.
The corresponding configuration for date formatting in application.properties should look like:
spring.jackson.write-dates-as-timestamps=false
I am implementing a Spring Data Repository and having my repository extend the MongoRepository. I am looking for a way to specify a hint on my findBy methods so I can be control. I have seen several times when a non-optimal index would be picked as the winning plan.
This is what my repository looks like right now:
public interface AccountRepository extends MongoRepository<Account, ObjectId> {
#Meta(maxExcecutionTime = 60000L, comment = "Comment" )
public List<Account> findByUserIdAndBrandId(Long userId, Long brandId);
}
I researched a bunch and found that the JPARepository from spring data supports the #QueryHint annotation but I do not believe that annotation is supported for MongoDb. Is there a similar annotation I can specify on top of my findBy method to specify the hint?
MongoTemplate allows to specify a hint, however, I have a ton of findBy methods and I would hate to add an implementation underneath just to specify a hint.
I would like to implement custom metric or statistics to my spring boot rest web service using actuator but i am not able to find simple tutorials.
For example:
how to show how many times a certain controller was called and what exact parameter field was filled?
how can i create a metric that when its URL is called, it runs certain query and shows back a json with some result
This seems like a good scenario for AOP (Aspect Oriented Programing) as this will allow you to separate this statistic logic from the business logic.
Have a look at Spring doc for more info about AOP and how to achieve that with Spring.
You can then define a pointcut on your controller and have a service for counting (and probably then storing) the data.
Refer below link
AOP Example
For point two the solution is to create an endpoint class (it can be or not a rest controller class). For example:
#Component
#RestControllerEndpoint(id = "pfm-statistics")
public class StatisticsEndpoint {
#GetMapping(value = "/", produces = "application/vnd.openxmlformats-
officedocument.spreadsheetml.sheet")
#ResponseBody
public byte[] generateStatisticsAsExcel() {
...
Note that the ID is the path to be called from URL. We can create a simple endpoint too and just return a string if we want. In this case instead of #RestControllerEndpoint annotation we can use #Endpoint, as a side note, the id should always contain dash