Is possible to get data from jpa/hibernate withou define entity or model in spring boot? - spring

Is possible to get data from jpa/hibernate withou define entity or model in spring boot? if possible, how to? thank you...

Yes its possible
for serverside and database you first read
https://spring.io/guides/gs/relational-data-access/
and for restful ,you must use RequestEntity<> to get a field(s) without a model and send or receive data from JSON.
// Field class is a response and this is not model class
public class Field{
private String name;
//getter and seter
}
#PostMapping("/test")
public void getFields(RequestEntity<Map<String,String>> entity){
Field field = new Field();
field.setName(entity.getBody().get("name"));
System.out.println(field);
}

It is possible to fetch the data without having it mapped to an entity by using nativeQuery and a Tuple class.
List<Tuple> resultList = entityManager
.createNativeQuery("select id as id, street as street, city as city, country as country from address ", Tuple.class
.getResultList();
Tuple firstResult = resultList.get(0);
assertEquals(1L , ((Number) firstResult.get("id")).longValue());
For more information you can read Vlad Mihalcea's blog post
https://vladmihalcea.com/the-best-way-to-map-a-projection-query-to-a-dto-with-jpa-and-hibernate/

Related

Fetch specific columns from an entity but not the entire entity

I have an entity:
#Entity
public class MailingList extends PanacheEntity{
public String name;
public String email;
public Organization organization;
.
.
.
}
So, I am trying to write a query to simply return me a list having the id and email only but not a list of the MailingList entities. I am using MySQL and I want something as shown here. I have read through different documentation but I haven't found something to solve my problem. Please help out.
Yes,
With panache it is possible to use DTO projections like in hibernate or jpa.
Here you have an example from the quarkus panache documentation on how to achieve a projection of only certain fields.

How can I map the fields return in JSON with my entity provided the key in JSON has different name than fields in my entity

I am trying to Map a JSON response to a Java POJO which has a different field name from different API.
I need an efficient way to do this reducing boilerplate codes.
I have tried mapping the JSON property field in Java POJO.
However, the problem is I am fetching data from different sources.
Let's say I have below user class
Class User{
String name;
String contact;
}
The JSON I may receive from different sources can be
{"name": "ABC" , "contact": "123456"}
or
{"userName": "XYZ" , "mobileNo":"4354665"}
There may be more variations as we go on integrating more API's
Is there a way I can archive this?
above is just a simple example
there could be more complex JSON object I may need to read.
like List of User etc.
You can use the #JsonAlias() to give the variable more than one JSON key binding.
#JsonAlias is introduced in Jackson 2.9 release. #JsonAlias defines one or more alternative names for a property to be accepted during deserialization i.e. setting JSON data to Java object. But at the time of serialization i.e. while getting JSON from Java object, only actual logical property name is used and not alias. #JsonAlias is defined as follows.
#Entity
Class User{
#JsonProperty()
#JsonAlias({"name", "userName"})
String name;
#JsonProperty()
#JsonAlias({"contact", "mobileNo"})
String contact;
}
You could use the #JsonSetter annotation like :
public class User{
public String contact;
public String name;
#JsonSetter("name")
public void setName(String name) {
this.name = name;
}
#JsonSetter("userName")
public void setName(String name) {
this.name = name;
}
}
Instead of directly mapping to an entity class , you should have a DTO object or model in between to map the json response. Then, you can convert that into any entity you may choose.If you are fetching the data from different sources , it means you are calling different endpoints, why don't you create different DTO 's for that.In that way even if one of the endpoints introduce a change , it won't affect the rest of the endpoint calls.
Vice-versa you could have different DTO objects being returned from the two endpoints instead of returning the same Entity class as well, that way you can have control over which attributes should be there in the response.
To reduce the boiler plate code, you could use library such as MAP STRUCT to enable conversion between entity and DTO objects easily
Read here about the advantages of using a DTO .

Have one Rest repository json with everything and one with fields excluded

I have two entities: Book and Category and a repository for both. In the controller, I have set up the methods correctly as such:
#RequestMapping(value="/books", method = RequestMethod.GET)
#CrossOrigin
public #ResponseBody List<Book> bookListRest() {
return (List<Book>) bookRepository.findAll();
}
This obviously shows all books and every field in the entity that isn't #JsonIgnore'd. The problem is, I need to have:
One page with Book data (book name, author name, isbn..) without category
One page with Category data (Category name) without books
One page with Everything (book data along with categories where they belong in)
How can one accomplish this?
I somehow need to in a way ignore #jsonignore on some occasions. Should I make a new entity that extends say, Question and also make a repository for that? Surely that can't be the correct way to do this.
As khalid Ahmed Said you can use costum dtos or you can add Filters to ignore specific fields in Jackson. First, we need to define the filter on the java object:
#JsonFilter("myFilterBook")
public class Book{
...
}
#JsonFilter("myFilterCategory")
public class Category{
...
}
Before you return your ResponseBody you try to use ObjectMapper (Jackson):
The case of one page with Book data (book name, author name, isbn..) without category:
ObjectMapper mapper = new ObjectMapper();
SimpleBeanPropertyFilter theFilter = SimpleBeanPropertyFilter
.serializeAllExcept("category");
FilterProvider filters = new SimpleFilterProvider()
.addFilter("myFilterBook", theFilter);
String dtoAsString = mapper.writer(filters).writeValueAsString(book);
You can do the same think by putting what you want o ignore for the other example.
And for more details to ignore field during marshalling with jackson you can check here
What about using DTOs data transfer objects
you can create multiple DTOs to use them in the response of your API
DTO is a pojo class that customize the returning data from your entity
public class BookWithoutCategoryDTO {
private String name;
private String authorName;
.....
/// and make setters and getters for them
}
public class BookWithCategoryDTO {
private String name;
private String authorName;
private String category;
.....
/// and make setters and getters for them
}
and create your custom mapper to convert from Book to BookDTO

Spring Boot map single JSON to two entities

A single JSON is posting from Postman and having two entity names as employee and employee address. From that JSON, empName should be stored in first entity and empAddress should be stored in second entity.
How to do this in Spring Boot? I tried to write only Entities.
First Entity:
class Employee{
private int emId;
private String empName;
//Getters;
//Setter;
}
Second Entity:
class EmployeeAddress{
private int emId;
private String empAddress;
//Getters;
//Setter;
}
My JSON: the firt value in JSON need to be stored in first entity and second need to be stored in second entity. How to do this in Spring Boot from controller?
{
"empName": "sam",
"empAddress:"chennai"
}
You need a DTO.
Something like this:
class Employee{
private String empName;
private String empAddress;
}
So, you can return this object as a Json

Ignoring spring mvc JSR-303 validations for selective entity fields

I have spring4 mvc application to save an Address entity, code bit as follows.
My Controller
#RequestMapping(value = "addAddress", method = POST)
public String registerComplaint(#Valid #ModelAttribute final Address address, final BindingResult resultBinder) {
if (resultBinder.hasErrors())
return "addAddress";
addressService.addAddress(address);
return "redirect:myAddress";
}
My Entity
#Entity
#Table(name = "address")
public class Address {
#NotNull
private String street;
#NotNull
private String pin;
#NotNull
private String createdBy;
........
}
My form conatins only street and pin as field, where as createdBy should be set by me after validating the other form values.
Here the problem is spring JSR303 validation support is validating a field ie createdBy which i don't want to validate by spring mvc.
How can i instruct spring mvc not to validate these kind of optional fields while using #Valid annotation.
Is there any way i can skip fields like this using spring mvc ?
Validation is mainly for user input. Since you will be setting createdBy yourself, just do so before saving it (e.g #PrePersist), or have a new Date as a default value. If you need to enforce a constraint for createBy, you can do so at the schema level.
#Column(nullable=false, ...)
private String createdBy = new Date();
You need to read up on Validation Groups. This lets you use different validators depending on the "scenario"
Use Spring's #Validated annotation to use groups
If you don't protect the createdBy field, a user can change it by altering the POST variables. See DataBinder.setDisallowedFields()
Conceptually, how is a pin related to an address?
It sounds like you want to use a Form Backing Object here (a regular non-JPA POJO made just for a form), and copy values to your real entities.

Resources