Add entity with OneToOne Relation using JPA and REST - spring

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);

Related

DTO and Entities mapping

I am building a Spring Rest Application, I need help with DTO's and parsing a result to a endpoint
This is json that I return at the moment to the endpoint:
{
"id": 1,
"name": "Ella - IPA Is Dead",
"description": "2015 IPA is Dead Series. Supremely floral, this hugely under-rated hop is related to Galaxy and was first cultivated in the Australian state of Victoria.",
"method": {
"mash_temp": [
{
"temp": {
"value": 65
}
}
]
}
}
I don't want to return "method" from this json, I just need "id", "name", "description", "mash_temp" - so it should look like this:
{
"id": 1,
"name": "Ella - IPA Is Dead",
"description": "2015 IPA is Dead Series. Supremely floral, this hugely under-rated hop is related to Galaxy and was first cultivated in the Australian state of Victoria. Initially given the same name as a certain Eurolager, their lawyers got involved and the St- prefix was dropped. Ella displays subtle notes of spice, but is fundamentally a truly floral bouquet, redolent of the Southern Hemisphere.",
"mash_temp": [
{
"temp": {
"value": 65
}
}
]
}
Those are the entities that I am using now:
Beer Entity:
#Entity
public class Beer implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "beer_id", unique = true, nullable = false)
private Integer id;
#Column(name = "name", nullable = false)
private String name;
#JsonProperty("description")
#Column(name = "description", nullable = false, columnDefinition = "TEXT")
private String description;
#JsonProperty("method")
#OneToOne(cascade = CascadeType.ALL)
private Method method;
}
Method Entity:
#Entity
public class Method implements Serializable
{
#JsonIgnore(value = true)
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#JsonProperty("mash_temp")
#OneToMany(cascade = CascadeType.ALL)
#JoinColumn(name = "mash_temp")
private List<MashTemp> mash_temp = new ArrayList<>();
}
MashTemp Entity:
#Entity
public class MashTemp implements Serializable
{
#JsonIgnore(value = true)
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#OneToOne(cascade = CascadeType.ALL)
private Temp temp;
#ManyToOne
private Method method;
}
Temp Entity:
#Entity
public class Temp implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private Integer value;
#JsonIgnore(value = true)
private String unit;
#OneToOne
private MashTemp mashTemp;
}
Does anyone know how to create DTO's from this Entities but without "method" field?
Also this is my Controller:
#GetMapping("/beers")
public ResponseEntity<Set<Beer>> getAllBeers()
{
return new ResponseEntity<>(beerService.getAllBeers(), HttpStatus.OK);
}
#GetMapping("/beers/{id}")
public ResponseEntity<Beer> getById(#PathVariable Integer id) {
Beer beer = beerService.findById(id);
return new ResponseEntity<>(beer, HttpStatus.OK);
}
Have a look at the #JsonUnwrapped annotation (https://fasterxml.github.io/jackson-annotations/javadoc/2.8/com/fasterxml/jackson/annotation/JsonUnwrapped.html). You can put it on the method field in the Beer class, and then the properties of the Method class are serialized directly on the same level as the ones from Beer.

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?

Spring JPA #ManyToOne and #OneToMany does not update all

I have two classes Post and Comment, one post can have multiple comments. So I have created my classes as follows:
Post:
#Entity
#Table(name = "posts")
public class Post extends AuditModel {
#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;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "post")
private Set<Comment> comments = new HashSet<>();
}
Comment:
#Entity
#Table(name = "comments")
public class Comment extends AuditModel {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
#Lob
private String text;
#ManyToOne(fetch = FetchType.EAGER, optional = false)
#JoinColumn(name = "post_id", nullable = false)
#OnDelete(action = OnDeleteAction.CASCADE)
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
#JsonIdentityReference(alwaysAsId = true)
#JsonProperty("post_id")
private Post post;
}
Post method:
#PostMapping("/posts")
public Post createPost(#Valid #RequestBody Post post) {
return postRepository.save(post);
}
Swagger request:
{
"id": 0,
"title": "string",
"description": "string",
"content": "string",
"comments": [
{
"id": 0,
"text": "string",
"post_id": 0
}
]
}
When I do a POST using the above schema, I am expecting that hibernate will insert data in both the tables. But instead, I get below error:
Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unresolved forward references for: ; nested exception is com.fasterxml.jackson.databind.deser.UnresolvedForwardReference: Unresolved forward references for:
at [Source: (PushbackInputStream); line: 1, column: 117]Object id [1] (for `com.example.jpa.model.Post`) at [Source: (PushbackInputStream); line: 1, column: 115].]
Can someone please help me to understand this and how can I achieve my requirement?

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

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();
}
}

Spring Data Rest - Creating the parent and embedded object in one request

I have a parent object that looks like this:
#Entity
public class Parent {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(unique = true, nullable = false)
#RestResource(exported = false)
private int pk;
#Column(nullable = false)
private String title
#Column(nullable = false)
#OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
private Set<Child> sentenceList;
}
And a child object that looks like this:
#Entity
public class Child {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(unique = true, nullable = false)
#RestResource(exported = false)
private int pk;
#Column(nullable = false)
private String title
#ManyToOne
#JoinColumn(nullable=false)
private Parent parent;
}
What I want to do is POST to the parent's repository to create the parent and also create the embedded children. The POSTed JSON would look something like this:
{
"title": "Parent"
[
{
"title": "Child 1"
},
{
"title": "Child 2"
},
]
}
Is this possible with Spring Data REST? I currently get an error stating that the parent PK can't be null.
Thanks for any help!

Resources