search phrase string using jpa queries - spring-data

I have a search with JPA query using Spring Data like this :
My interface repository :
public interface AnnonceDao extends JpaRepository<Annonce, Integer> {
Page<Annonce> findByTitreContaining(String titre,Pageable page);
}
when I look for something like Hello Friend I get all entities that have Hello Friend concatened , I want something to get Friend Hello too or any entity that contains Hello or Friend. what I can use as Query, thanks for your help.

This should work:
public interface AnnonceDao extends JpaRepository<Annonce, Integer> {
Page<Annonce> findByTitreContainingAndTitreContaining(
String part1,
String part2,
Pageable page
);
}
If the number of terms you want to pass is unknown at compile time, as you explain in the comment you can use Specifications.
This leaves the task of creating the specification to the client of the repository. If you don't like that you can provide a custom method and dynamically create a query inside. Again you have the choice of multiple technologies:
SQL
JQL
QueryDsl
QueryDsl looks actually really nice and readable as you can see in the linke example.

Related

What is the best way to name REST resources when returning same resource but using different DTO?

I'm curious what is the best way of returning the same resource but using different DTOs.
For example, I have a user class:
public class User {
private String name;
private String surname;
private String age;
}
The list of users is available under url:
/users
Some other view needs list of users but without age, so, I would like to return list of UserDTO.
public class UserDTO {
private String name;
private String surname;
}
What is the proper way of defining url?
/userDtos - this is bad, because I can have more than one DTOs for representing users,
/users/dto - this is also bad
/users?name=true,surname=true - this one is also bad, it indicates that we are filtering the result, but we are not; we're just filtering fields.
For sure someone already had this problem before, but I couldn't find anything on the Internet.
A similar concept is called partial response which provide an option to let client to specify which fields to include in the response using the query parameters like:
:
/user?fields=name,surename
Basically you define a syntax for you own query language to represent a selection of fields. Here and Google Cloud API are some examples.
By taking this concept to a more coarse-grained level , you can use query parameter "view" to define different predefined combination of fields such as:
/users //default view if no "view" query parameter is specified
/users?view=admin //maybe this view will not show age field
/users?view=hr //maybe this view only show the fields that are accessible to HR

Spring-restdocs field description from annotations

Is it possible to use annotations (at field-level) to provide description for fields?
I know I can use description method for that
.andDo(document("index", responseFields(
fieldWithPath("contact").description("The user's contact details"),
but I would prefer to put that description together with field definition, in my response object.
class IndexResponse {
//The user's contact details
String contract;
}
I know that I could have generated constraint descriptions (http://docs.spring.io/spring-restdocs/docs/current/reference/html5/#_using_constraint_descriptions_in_generated_snippets) but it generated description only for validation annotations.
I am looking for something like https://github.com/swagger-api/swagger-core/wiki/Annotations#apimodelproperty from Swagger.
It doesn't. I'm the lead of the REST Docs project and it's my opinion that annotations aren't a good way to write documentation. If you disagree with that opinion and want to use annotations, you could write an add-on that's similar to what's done from constraint descriptions. You could pass it a class to introspect and automatically generate FieldDescriptor instances that you can then pass into the request and response field snippets.
We built an extension to Spring REST Docs that allows using Javadoc for field descriptions:
class IndexResponse {
/**
* The user's contact details
*/
String contract;
}
But currently this only works if Jackson and MockMvc tests are used.
Project: https://github.com/ScaCap/spring-auto-restdocs
An introduction article: https://dzone.com/articles/introducing-spring-auto-rest-docs

With Spring Data REST, how to make custom queries use the HATEOAS output format?

I'm learning the Spring 4 stuff by converting an existing Spring 3 project. In that project I have a custom query. That query fetches data in a straightforward way, after which some heavy editing is done to the query results. Now the data is sent to the caller.
I plan on extending CrudRepository for most of my simple query needs. The data will be output in HATEOAS format.
For this custom query I think I should be adding custom behavior (spring.io, "Working with Spring Data Repositories", Section 1.3.1, "Adding custom behavior to single repositories").
As an example:
#Transactional(readOnly = true)
public List<Offer> getFiltered(List<Org> orgs, OfferSearch criteria) {
List<Offer> filteredOffers = getDateTypeFiltered(criteria);
filteredOffers = applyOrgInfo(orgs, filteredOffers);
filteredOffers = applyFilterMatches(filteredOffers, criteria);
return sortByFilterMatches(filteredOffers);
}
(The code merely illustrates that I don't have a simple value fetch going on.)
If I could use the raw results of getDateTypeFiltered(criteria) then I could put that into a CrudRepository interface and the output would be massaged into HATEOAS by the Spring libraries. But I must do my massaging in an actual Java object, and I don't know how to tell Spring to take my output and emit it in my desired output format.
Is there an easy way to get there from here? Or must I try things like do my filtering in the browser?
Thanks,
Jerome.
To properly get HAL formatted results, your query controllers must return some form of Spring HATEOAS Resource type.
#RequestMapping(method = RequestMethod.GET, value = "/documents/search/findAll")
public ResponseEntity<?> findAll() {
List<Resource<Document>> docs = new ArrayList<>();
docs.add(new Resource<Document>(new Document("doc1"), new Link("localhost")));
docs.add(new Resource<Document>(new Document("doc2"), new Link("localhost")));
Resources<Resource<Document>> resources = new Resources<Resource<Document>>(docs);
resources.add(linkTo(methodOn(ApplicationController.class).findAll()).withSelfRel());
resources.add(entityLinks.linkToCollectionResource(Document.class).withRel("documents"));
return ResponseEntity.ok(resources);
}
I have submitted a pull request to Spring Data REST to update its reference docs to specify this in http://docs.spring.io/spring-data/rest/docs/2.4.0.RELEASE/reference/html/#customizing-sdr.overriding-sdr-response-handlers
I am not sure I perfectly got your question. If I did this should be the answer: http://docs.spring.io/spring-data/jpa/docs/1.9.0.RELEASE/reference/html/#repositories.custom-implementations

WCF - Entity Framework - ERR_CONNECTION_RESET

I got a problem with my WCF service. Here is the
[OperationContract]
[WebGet(UriTemplate = "/needs", ResponseFormat = WebMessageFormat.Json)]
List<CustomerNeed> getAllCustomerNeeds();
When I go on the page which call this service, I got this error
GET http://localhost:666/rest/Service1.svc/needs net::ERR_CONNECTION_RESET
When I'm trying to return a string instead of a List, it works.
CustomerNeed is a class generate from my database via EntityFramework.
In my service, I'm only calling an other method which is in an other class;
public List<CustomerNeed> getAllCustomerNeeds()
{
var needs = from cn in db.CustomerNeeds
select cn;
List<CustomerNeed> list = new List<CustomerNeed>();
foreach (CustomerNeed cusN in needs)
{
list.Add(cusN);
}
return list;
}
Maybe is it because I have a foreign key in my table CustomerNeed ?
When I do "LINQ to entities" to import my database, do I have to import tables that were created because of many to many relation ?
I will recommend you to create a simple custom class which will represent your CustomerNeeds database entity, initiate this object on the server side and pass to the client application. It can help you to avoid this problem and also it is recommended way to transfer data accross the WCF services.
In this case you need to do the next steps:
1) Create a public class CustomerNeeds and mark it with the DataContract attribute. For example:
[DataContract]
public class CustomerNeeds
{
[DataMember]
public SomeDataType PropertyName {get; set;}
}
2) Initiate this object on the service, change return datatype in getAllCustomerNeeds() method from the entity class to the newly created class CustomerNeed and pass this data to the clien
And that`s all.
You haven't shown where/what db is, but I'm assuming if you're using entity framework as your tag implies it's a entities context. You might be having some issues with the context already being disposed or not newed up correctly (though I would have expected you to receive a slightly different error if that's the case.)
It looks like you're going through some unnecessary steps in your function, I would think something like this would work:
public List<CustomerNeed> getAllCustomerNeeds()
{
using (var db = new YourContext()) // plug in your context object
{
return db.CustomerNeeds.ToList();
}
}
Additionally when you say it "works as a string" are you returning something small like "hello world"? you might need to take a look at your WCF configuration to make sure it can handle the amount of data you're trying to pass back and forth.
Hope this helps!

How to sort dojox.grid.DataGrid with wink-based REST API?

I'm using the Dojo datagrid client side, it works well and according to documentation it generates the following GET request when clicking on the column header:
GET http://localhost:8080/books/rest/books?sort(+isbn)
Problem is that I can't interpret the query parameter "sort(+isbn)" on the server side using the Apache Wink framework, because there's no value set for it. E.g. I'd expect something like "sort=+isbn" instead.
Here's my server side code:
#Path("/books")
public class BookServiceImpl implements BookService {
...
#GET
#Produces(MediaType.APPLICATION_JSON)
public String getBook(#QueryParam("sort") String sortBy) {
System.out.println("Received Queryparam for sort is " + sortBy);
return "";
}
}
Since "sort(+isbn)" has no value assigned to it, it appears to be an invalid query parameter. Not sure why Dojo datagrid uses this convention.
Would appreciate help as to how to work around this on the Java side, ideally using Wink or another mechanism to process GET requests.
Try to use #Context UriInfo to get the full uri info, call to UriInfo.getQueryParameters to get all query params. I believe sort(+isbn) will be there.