I need to update entity in hibernate, like
class EntityA {
private String name
//one-to-many, orhpan removal = true, bidirectioanl
private List<EntityB> listB;
}
I recieve the object from REST API, and I need to update item in the listB and name for Entity A.
Items in the list can be updated/removed/added
What is the best practice to this, from hibernate perpective ?
The first thing is what is the format of representation resources which you invoking using http request.
JSON
XML
If your resource format is json then you gonna map json object to your java object and manage it with JPA.
Example :
Lets say your json format resource contain following user data called user_info.json
{
"firstName" : "jack",
"lastName" : "Dawson",
"contacts" : [
{
"cellphone" : "434343",
"address" : "agrabad",
"city" : "ctg"
},
{
"cellphone" : "+88667755",
"address" : "chokbazar",
"city" : "dhk"
}
]
}
And your user pojo class is :
public class User {
Private String firstName;
Private String lastName;
private Collection<Contact> contacts;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Collection<Contact> getContacts() {
return contacts;
}
public void setContacts(Collection<Contact> contacts) {
this.contacts = contacts;
}
}
There is lot of json lib, i personally prefer Gson developed by Google.
So using Gson you can map json object to java object. Following code snippet about mapping json to java object :
User user = new Gson().fromJson("user_info_Json_String", User.class)
So you have done with mapping. All you have to do execute user object according to EntityManager operation.
Note: User class state has to match json key string during mapping.
If resource format is XML then JAXB is great feature for marshalling and unmarshalling e.g object to xml and vice-versa.
Update : To update collection of contacts to database we don't need to add element one by one. Java Collection has method call addAll(). Just using it . Here is the example :
Collection<Contacts> jsonUserContacs = user.getContacts();
Collection<Contacts> dbContacts = dbuser.getContacts();
dbContacts.addAll(jsonUserContacs);
Thats it. You don't need to add contact one by one.
Hope This knowledge transfer helps you. Thanks.
Related
I am trying to map a JSON structure to a specific POJO that doesn't really match the JSOM, here is a simple example:
JSON
{
"strA": "MyStr",
"Street": "1st Lane",
"Number": "123"
}
POJO
#JsonIgnoreProperties(ignoreUnknown = true)
public class ClassA {
#JsonProperty("strA")
private String strA;
private Address address;
//Constructor, getter,setter
#JsonRootName("Address")
#JsonIgnoreProperties(ignoreUnknown = true)
public class Address {
private String address;
public Address() {
}
public String getAddress() {
return address;
}
#JsonAnySetter
public void setAddress(#JsonProperty("Street") String street, #JsonProperty("Number")String number) {
this.address = number + " " + street;
}
}
Now, Address is properly created from the sample JSON (only made it work with the JsonAnySetter unfortunately), but I can't get ClassA to be created properly.
I've tried annotating the Address property of it, but to no avail.
How can I achieve this in a "simple" way? This is important as this example is simple, but my real use cases involves several composed classes that need information from the JSON root + from complex JSON elements with different names.
Thank you for your time.
I'm working with java project using spring REST.
My problem that i could not extract data from request body (which is json) after receive it as enitiy.
for example:
JSON Request Body
{
"firstname": "Rayan",
"lastname": "Cold",
"company_id": 23
}
My Controller maaped method is:
#PostMapping("/employee")
public Employee createEmployee(#RequestBody Employee employee) {
// Here i need to extract the company id from request body
// Long companyId = *something* // how i can extract from request ?
return companiesRepository.findById(companyId).map(company -> {
employee.setCompany(company);
return employeeRepository.save(employee);
}).orElseThrow(() -> new ResourceNotFoundException("Company not found"));
}
I know i can pass company ID as path variable. But i do want it in request body not in URI.
Thanks
company_id can not be mapped if your Employee class contains companyId.
I guess your company class like:
public class Employee {
private String firstname;
private String lastname;
private Long companyId;
//skip getter setter
}
change it to :
public class Employee {
private String firstname;
private String lastname;
#Transient
#JsonProperty("company_id")
private Long companyId;
//skip getter setter
}
You can simply take the company id from the object received:
employee.getCompany_id();
Please ensure, your Employee class should be something like below:
public class Employee
{
private String company_id;
private String lastname;
private String firstname;
// getter and setters of all these member fields
}
Name of the variables should be same as the one in JSON or use the
appropriate annotations.
I have tested a Rest API using postman and while testing on selection raw option, it shows unsupported media for application/json header content type, but only working with url-encoded form. Please specify how to use #FormParam for application/json content type. Thanks in advance.
The #FormParam annotation is only used to access parameters passed in a normal form that usually uses x-www-form-urlencoded. If you're sending your data as a JSON in request body, you can just create a POJO class corresponding to your request body containing all properties of your JSON request and use it as the parameter of your REST method. The JAX-RS container automatically deserializes the JSON body of the request into the given object for you.
As an example, if your request body is something like this:
{
"firstName" : "Foo",
"lastName" : "bar"
}
Then you can define a POJO representing your request data as below:
public class PersonRequest {
private String firstName;
private String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
And define your REST endpoint to access this data as:
#POST
#Path("/persons")
#Consumes("application/json")
public String savePerson(PersonRequest personRequestData) {
// request data are deserialized into the personRequestDataas properties
System.out.println(personRequestData.getFirstName());
}
You don't need to specify any sort of annotation on your POJO class.
I am writing a JSP webapp and right now I'm kind of stuck. I have been using an ArrayList of Java Objects, each with a list of properties. They are Order objects with properties like firstName, lastName, etc. At this point in my development I need to store the individual orders as JSON arrays in javascript variables. I am able using a servlet to convert the arraylist to JSON but the JSON has repeat properties for each of the Order objects, like this:
[{firstName : Mike, lastName : Daniels, ..... firstName : John, lastName : Doe ... etc ...}]
Clearly, the JSON is made up of all of my Order objects, strung together as one JSON array. What I am wondering is how I need to split up the string into separate variables depending on the number of Orders in the app at the time.
Here's how the object is set if it helps. Thanks!
Object orders = request.getSession().getAttribute("orders");
//this is a string of order properies/values
String json = new Gson().toJson(orders);
HttpSession session = request.getSession();
session.setAttribute("jsonOrders", json);
Try iterating through the array list, creating a JSON object for each of the objects instead of converting the array list as a whole.
Let's suppose your orders entity is something like this:
public class Order {
private String firstName;
private String lastName;
// getters & setters
}
and you get your orders data in request like:
[{
"firstName": "Mike",
"lastName": "Daniels"
}, {
"firstName": "John",
"lastName": "Doe"
}]
You should be able to convert it to List<Order> using
List<Order> orders = gson.fromJson(response, Order.class);
You can then iterate over the list like:
for (Order order: orders) {
// Whatever you want to do
}
Or, if you are using java 8:
orders.forEach (order -> System.out::println);
Here is the solution using Gson library,
//Order.java
public class Order {
private String firstName;
private String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
//Orders.java
public class Orders {
Order[] order;
public Order[] getOrder() {
return order;
}
public void setOrder(Order[] order) {
this.order = order;
}
}
import com.google.gson.Gson;
//Solution.java
public class Solution {
public static void main(String[] args) {
String json = "{\"order\":[{\"firstName\":\"Mike\",\"lastName\":\"Daniels\"},{\"firstName\":\"John\",\"lastName\":\"Doe\"}]}";
Orders orders = new Gson().fromJson(json, Orders.class);
Order[] orderArr = orders.getOrder();
for(int i=0; i<orderArr.length;i++){
System.out.println("First Name : "+ orderArr[i].getFirstName());
System.out.println("Last Name "+orderArr[i].getLastName());
}
}
}
**Output**
First Name : Mike
Last Name Daniels
First Name : John
Last Name Doe
Answer by ssc looks right. Best way to do is iterate through the list.
I am following this spring guide:
https://spring.io/guides/gs/accessing-mongodb-data-rest/
Everything is perfect, however if I want to POST a document with manual id, I am not able to do that.
Here is what all I have done:
I inserted one document from Mongo shell by the command db.person.insert({"_id": "111111", "firstName" : "Vikas", "lastName" : "Prasad"});
This works fine and if I do a GET at http://localhost:8080/people from Postman, I can see the person document with id 111111 in the response having self href as http://localhost:8080/people/111111
But if I am sending a POST request from Postman at http://localhost:8080/people with body as {"_id": "222222", "firstName" : "Aadish", "lastName" : "Patodi"}, the document is getting inserted with an auto id instead of 222222. Because of which obviously I cant access this docuemnt by doing a GET at http://localhost:8080/people/222222 unlike the case when I used insert() from the shell to insert a document with manual id. Instead I have to hit a GET at http://localhost:8080/people/57bc29ada3fab115cc9b546b to fetch this second document.
Just to check if I am POSTing the {"_id": "222222", "firstName" : "Aadish", "lastName" : "Patodi"} again, its getting inserted again at a new auto generated id: http://localhost:8080/people/57bc2bdaa3fab115cc9b546c. It means MongoDB is not even looking at the _id, else it must have thrown duplicate key error.
I tried searching various sources. All I can found is an implementation of the data access code separately in JAVA at back end and calling respective MongoDB methods.
My question is:
Just like in the given tutorial they are performing every operation without defining any JAVA back end code for data access from MongoDB for auto id documents, is there a way to do the same for manual id documents?
Or just for this one use case I have to implement the data access code at the back end?
I am using CorsFilter to handle cross origin requests.
Edit:
Below is the Person class:
package hello;
import org.springframework.data.annotation.Id;
public class Person {
#Id private String id;
private String firstName;
private String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
I have tried:
-> adding getter and setter for id attribute
-> renaming id to employeeNumber
-> renaming id to employeeNumber and adding getter and setter for employeeNumber
None of the above three solved the issue.
as discussed on the comment, looks like your _id field is not mapped correctly. Can you check if the _id is mapped correctly in the pojo ?
Finally, I got it working by renaming id with _id and adding getter and setter for the same in the Person class.
package hello;
import org.springframework.data.annotation.Id;
public class Person {
#Id private String _id;
private String firstName;
private String lastName;
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}