How to map a nested JSON Object as an SQL table row in Spring Boot - spring

I'm using Spring to develop APIs along with JPA. I'm handling a POST request that accepts #RequestBody as a JSON object that looks like this-
{
"id": "323",
"name": "Sam",
"gpsLocation": {
"latitude": 66.7492558,
"longitude": 97.133258
}
}
And an SQL User Table that has the following columns-
id | name | latitude | longitude
Is there a way in Spring to map this nested json object directly to these table columns?
This is what my User.java and GpsLocation.java entity classes look like right now-
#Table(name = "user")
#Entity
public class UnderObservation {
#Column(name = "name", nullable = false)
private String name;
#Id
#Column(name = "id", nullable = false)
private String userID;
private GpsLocation location;
}
#Entity
public class GpsLocation {
#Column(name = "Latitude", nullable = false)
private Double Latitude;
#Column(name = "Longitude", nullable = false)
private Double Longitude;
}
I'm looking for a way to "flatten/unwrap" GpsLocation class so that it directly fits into the User table instead of having a separate table for GpsLocation.
I can not change the JSON Structure because some other No SQL Databases are using this. Also, I'm new to Spring!

The best practice here is using DTO data transfer object that hold the request body
and map it to the user object using external library like mapstruct, ObjectMapper or even do it manually
the DTO is a pojo Object carries data between processes

Try This way with a Constructor:
#Getter
#Setter
#Table(name = "user")
#Entity
public class UnderObservation {
#Column(name = "name", nullable = false)
private String name;
#Id
#Column(name = "id", nullable = false)
private String userID;
#Column(name = "latitude", nullable = false)
private Double latitude;
#Column(name = "longitude", nullable = false)
private Double longitude;
private GpsLocation location;
UnderObservation(String name, String userID, GpsLocation location) {
this.name = name;
this.userID = userID;
this.location = location;
this.latitude = this.location.getLatitude();
this.longitude = this.location.getLongitude();
}
}

Related

how to add object with fk to table in jparepository

i had scheme of user parking and detail parking.
user can park many times (one to many)
im trying to add detail parking object to my db, but i dont have idea how to add the fk from the user in the row of the table, its gave me null there.
(ignore from the logic of the model, i just want to understood the logic how can i the object with fk of ther entity)
this is my code:
#PostMapping("/parking")
public String saveCarParking(#ModelAttribute("user") parkingUsers parkingUsers) {
// parkingUsers[id, firstName, lastName, license]
parkingUsers p = new parkingUsers("jhon", "nash", "248651355");
parkingUsersService.saveParkingUser(p);
// parkingDetails[id, entryDate, entryTime, exitDate, exitTime, user_id(FK)]
parkingDetails d = new parkingDetails(LocalDate.now(), null, LocalDate.now(), null);
parkingDetailsService.saveParkingUser(d);
//how i connect parkingDetails object with fk of parkingUsers?
//it adding now row of parkingDetails but without the fk of user
return "redirect:/parkingList";
}
parking user entity:
#Entity
#Table(name ="users")
public class parkingUsers {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "license")
private String license;
#OneToMany(mappedBy = "parkingUsers", cascade = CascadeType.ALL, orphanRemoval = true)
private List<parkingDetails> parkingDetails = new ArrayList<parkingDetails>();
public parkingUsers() {
}
public parkingUsers(String firstName, String lastName, String license) {
this.firstName = firstName;
this.lastName = lastName;
this.license = license;
}
//setter gettrs and tostring...
entity class of details parking
#Entity
#Table(name ="details")
public class parkingDetails {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "entry_date")
private LocalDate entryDate;
#Column(name = "entry_time")
private LocalDateTime entryTime;
#Column(name = "exit_date")
private LocalDate exitDate;
#Column(name = "exit_time")
private LocalDateTime exitTime;
#ManyToOne
#JoinColumn(name="user_id")
private parkingUsers parkingUsers;
public parkingDetails() {}
public parkingDetails(LocalDate entryDate, LocalDateTime entryTime, LocalDate exitDate, LocalDateTime exitTime) {
this.entryDate = entryDate;
this.entryTime = entryTime;
this.exitDate = exitDate;
this.exitTime = exitTime;
}
//test
// public parkingDetails(LocalDate entryDate, LocalDateTime entryTime, LocalDate exitDate, LocalDateTime exitTime, int user_id ) {
// this.entryDate = entryDate;
// this.entryTime = entryTime;
// this.exitDate = exitDate;
// this.exitTime = exitTime;
// this.parkingUsers.setId(user_id);
// }
//setter gettrs and tostring...
In the ParkingDetails entity, you can have a setter for "parkingUsers" variable to set user object.
In your REST api's saveCarParking() method, before calling "parkingDetailsService.saveParkingUser(d);" you can pass the user object to ParkingDetails using setter created in ParkingDetails.
This should work. No need to explicitly extract the user_id from user's object to pass into ParkingDetails.
Adding one more parameter of type ‘parkingUsers‘ in the constructor of ‘ ParkingDetails’ to initialize user in parking class will also work.
(Apart, it is a good practice to start the class name with a capital letter e.g. instead of having class name as parkingDetails, it should be ParkingDetails.)

Caused by: javax.persistence.NonUniqueResultException: query did not return a unique result: 2 For Save data

I can not save Data. When I saved post request got error?
#Entity
#Table(name = "ALKP")
public class ALKP {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String title;
#Column(name = "KEYWORD")
private String keyword;
private String code;
private Long slNo;
private String fullName;
private boolean isActive;
#CreationTimestamp
#Column(name = "created_at",updatable = false)
private LocalDate createDate;
#UpdateTimestamp
#Column(name = "updated_at")
private LocalDateTime updateDateTime;
#ManyToOne
#JoinColumn(name="parentId")
public ALKP parentId;
#OneToMany(mappedBy="parentId")
public Set<ALKP> subALKP = new HashSet<>();
Data ::
PostMan Body Request Data
{
"title": "FeMale",
"keyword": "GENDER_FEMALE",
"slNo": 2,
"active": true,
"code": "MC-00209",
"fullName": "FEMALE",
"parentId":700
}
"message": "detached entity passed to persist error in Spring Boot when consuming a rest service",
When I saved data it can not be catch Parent ALKP . I think It can be
parentId:{
"id":700
}
seems your ALKP enity have same parentId. or your defined the association mab be wrong.
#ManyToOne
#JoinColumn(name="parentId")
public ALKP parentId;
#OneToMany(mappedBy="parentId")
public Set<ALKP> subALKP = new HashSet<>();
Above both are pointng same ALKP and its Id then how can you get one and many object in same enity?

How to map the result set with specific columns of a JPQL query with dynamic projections to an entity

I am querying a database using jpql and my query is getting generated dynamically, i.e, both projections and predicates. However, I am not able to map the result set to get proper JSON response.
Entitlement Entity
#Entity
public class Entitlement{
#Id
#GenetedValue(strategy = GenerationType.AUTO)
private Integer id;
#Column(name = "license_id")
private String licenseId;
#Column(name = "customer_id")
private String customerId;
#OneToOne
#JoinColumn(name="product_uuid")
private Product product;
//setter getters and constructors
}
Product Entity
#Entity
public class Product{
#Id
#GenetedValue(strategy = GenerationType.AUTO)
#Column(name="product_uuid")
private Integer id;
#Column(name = "isbn")
private String isbn;
#Column(name = "title")
private String name;
//setter getters and constructors
}
EntitlementDaoImpl.java
Query query = entityManager.createQuery("select e.customerId,e.licenseId,p from Entitlement
e,Product p where e.product_uuid = p.product_uuid");
List<Entitlement> list = query.getResultList();
return list;
JSON response Received:
[
"customer101",
"license123",
"product": {
"id":201
"isbn":"abvhgfdWDMNB"
"name":"sample_book"
}
]
Expected JSON:
[
"customerId":"customer101",
"licenseId":"license123",
"product": {
"id":201
"isbn":"abvhgfdWDMNB"
"name":"sample_book"
}
]

Need solution for following scenario in Hibernate many to many mapping

Consider the tables where posts and tags exhibit a many-to-many relationship between each other.
The many-to-many relationship is implemented using a third table called post_tags which contains the details of posts and their associated tags.
Post Model
#Entity
#Table(name = "posts")
public class Post {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
#Size(max = 100)
#Column(unique = true)
private String title;
#NotNull
#Size(max = 250)
private String description;
#NotNull
#Lob
private String content;
#NotNull
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "posted_at")
private Date postedAt = new Date();
#NotNull
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "last_updated_at")
private Date lastUpdatedAt = new Date();
#ManyToMany(fetch = FetchType.LAZY,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
#JoinTable(name = "post_tags",
joinColumns = { #JoinColumn(name = "post_id") },
inverseJoinColumns = { #JoinColumn(name = "tag_id") })
private Set<Tag> tags = new HashSet<>();
public Post() {
}
public Post(String title, String description, String content) {
this.title = title;
this.description = description;
this.content = content;
}
// Getters and Setters (Omitted for brevity)
}
TAG Model
#Entity
#Table(name = "tags")
public class Tag {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
#Size(max = 100)
#NaturalId
private String name;
#ManyToMany(fetch = FetchType.LAZY,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
},
mappedBy = "tags")
private Set<Post> posts = new HashSet<>();
public Tag() {
}
public Tag(String name) {
this.name = name;
}
// Getters and Setters (Omitted for brevity)
}
Problem is
I tried to use an existing tags. and insert happened only on posts & posts_tags table.
Initially i'm Get tag(s) with tagName(s). Once you have the Tag object, you can set it in the Post object and save it.
Like this
Post post = new Post("Hibernate Many to Many Example with Spring Boot",
"Learn how to map a many to many relationship using hibernate",
"Entire Post content with Sample code");
// Create two tags
Tag tag1 = tagService.getTag("Spring Boot");
// Add tag references in the post
post.getTags().add(tag1);
postRepository.save(post);
If I do like that, entry is not available in post_tags table.
Tag Repository and Tag Service:
#Repository
public interface TagRepository extends JpaRepository<Tag, Long> {
#Query("select p from Tag p where p.name = :name")
Tag findByName(#Param("name") String name);
}
#Override
public Tag findByName(String name) {
return repository.findByName(name);
}

Add entity with OneToOne Relation using JPA and REST

I am using Spring JPA Restful, and I don't understand how to insert an entity with a foreign key.
Activity Entity:
#Entity
#Table(name= "Activity")
public class Activity implements Serializable{
#Id
#GeneratedValue(generator = "uuid")
#GenericGenerator(name="uuid", strategy = "uuid2")
#Column(name = "uuid", nullable = false, unique = true)
private UUID uuid;
#OneToOne(fetch = FetchType.EAGER, cascade=CascadeType.MERGE)
#JoinColumn(name="type", nullable = false)
private ActivityType type;
#Column(nullable = false)
private String label;
ActivityType Entity:
#Entity
#Table(name= "ActivityType")
public class ActivityType implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column(nullable = false, unique = true)
private String code;
#Column(nullable = false
private String label;
Is it possible to insert Activity simply? With something like this JSON where ActivityType's id "1" exists:
createActivity:
{"label":"LABEL","type":1}
With this code I have to do:
createActivity:
{"label":"LABEL","type":{"id":1}}
which return value is:
{
"uuid": "a54b27aa-8d49-41fd-8976-70c019c40e3b",
"type": {
"id": 1,
"code": null,
"label": null
},
"label": "LABEL",
"details": null
}
I use the library gson for parsing domain classes into JSON.
//... code for making your activity, let's say you have an Activity object myActivity
Just add the following code where you want to parse your object into JSON.
Gson gson = new GSON();
String json = gson.toJson(myActivity);

Resources