Links with list of entities are getting rendered for any link instead of proper page in Spring boot application - spring

I am relatively new to the Spring boot application. This has been working fine lately until I introduced a new entity as follows:
#Entity
#Table(name = "student_resource_access")
public class StudentResourceAccess extends implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private StudentResourceAccessPK studentResourceAccessPK;
#MapsId("studentId")
#ManyToOne
#JoinColumn(name = "student_id", referencedColumnName = "id")
private Student student;
#MapsId("userId")
#OneToOne
#JoinColumn(name = "user_id", referencedColumnName = "id")
private User user;
#Enumerated(EnumType.STRING)
#Column(name = "role")
private UserRole role;
}
Associated PK class is as follows:
#Embeddable
public class StudentResourceAccessPK implements Serializable {
private String studentId;
private String userId;
#Column(name = "external_entity_type")
#Enumerated(EnumType.STRING)
private ExternalEntityType externalEntityType;
}
Now after making this change, when I am launching my Spring boot application, any link I would like to browse, I am seeing very weird content just like below:
{
"_links" : {
"entity1" : {
"href" : "https://example.com/entity1{?page,size,sort}",
"templated" : true
},
"entity2" : {
"href" : "https://example.com/entity2{?page,size,sort}",
"templated" : true
},
...
"studentResourceAccess" : {
"href" : "https://example.com/studentResourceAccess{?page,size,sort}",
"templated" : true
},
..
I don't have any idea, why is this coming and how should I fix this? Could anyone please help here? Thanks.
EDIT:
I have spring-data-rest in the dependency tree for a long time. This has been working fine. Suddenly with the above change, as I mentioned, it started behaving this way. No idea, why is this happening.

Related

#OnetoMany entity in #ElementCollection

I have 2 entities and 1 embeddable object :
#Entity
class CourseDetails extends Course {
#Id
Integer id;
#ElementCollection
#CollectionTable(name = "course_section", joinColumns = #JoinColumn(name = "courseId"), foreignKey = #ForeignKey(name = "course_section_fk"))
private List<CourseSection> courseSection;
}
#Embeddable
public class CourseSection extends BaseBo {
#OneToMany
#JoinColumn(name="contentId")
private Set<CourseContent> courseContent = new HashSet<>();
}
#Entity
public class CourseContent {
private static final long serialVersionUID = 1856738483334146418L;
#Id
private Integer contentId;
private String contentSummary;
}
I want to store coursesection as an embedded object of course and course_section should contain reference of course_content. I tried the above structure but it gives error :
#ElementCollection cannot be used inside an #Embeddable that is also contained within an #ElementCollection
How to achieve this in spring boot-jpa ?

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.

Spring boot REST API not returnning expect Json data

I just begin my first web application using Spring Boot, and I create the first project as well as the Database for this project. It used to fine to return the list of products with encapsulated datas that a product has. When I leave it for several Days and come back, the query api return instead of the products themselves but links.
so when I type "http://localhost:8080/api/products/1" in the browser, it return this
unexpected return JSON data.
Where it use to return something like
{
"sku" : "BOOK-TECH-1000",
"name" : "Crash Course in Python",
"description" : "Learn Python at your own pace. The author explains how the technology works in easy-to-understand language. This book includes working examples that you can apply to your own projects. Purchase the book and get started today!",
"unitPrice" : 14.99,
"imageUrl" : "assets/images/products/books/book-1000.png",
"active" : true,
"unitsInStock" : 100,
"dateCreated" : "2021-01-04T21:05:48.000+0000",
"lastUpdated" : null,
"_links" : {
"self" : {
"href" : "http://localhost:8080/api/products/1"
},
"product" : {
"href" : "http://localhost:8080/api/products/1"
},
"category" : {
"href" : "http://localhost:8080/api/products/1/category"
}
}
}
I dont know why the data informations are not return anymore, any suggestion?
The return page of the GET query
The DAO class I Created for the JPA
The product class
database data, which is what should be return in the result page
Product.java:
import lombok.Data;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import javax.persistence.*;
import java.math.BigDecimal;
import java.util.Date;
#Entity
#Table(name="product")
#Data
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
//join with Entity "ProductCategory". vise verse, many products to one product Category.
#ManyToOne
#JoinColumn(name = "category_id", nullable = false)
private ProductCategory category;
#Column(name = "sku")
private String sku;
#Column(name = "name")
private String name;
#Column(name = "description")
private String description;
#Column(name = "unit_price")
private BigDecimal unitPrice;
#Column(name = "image_url")
private String imageUrl;
#Column(name = "active")
private boolean active;
#Column(name = "units_in_stock")
private int unitsInStock;
#Column(name = "date_created")
#CreationTimestamp
private Date dateCreated;
#Column(name = "last_updated")
#UpdateTimestamp
private Date lastUpdated;
}
ProductRepository.java:
import com..Entity.Product;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.web.bind.annotation.CrossOrigin;
#CrossOrigin("http://localhost:4200")
public interface ProductRepository extends JpaRepository<Product, Long> {
}
I faced something similar due to lombok not working popery. Writing the getter and setter manually should work. In my case, adding lombok extension for vs code solved the problem.

non fetched entity appears in JSON result

I have a user entity:
#Entity(name = "users")
#DynamicUpdate
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
#JsonIgnore
#JsonIgnoreProperties("user")
private Set<Car> cars;
}
and a car entity:
#Entity(name = "cars")
#DynamicUpdate
public class Car implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(name = "plate_number")
#JsonView(View.Summary.class)
private String plateNumber;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="user_id")
#JsonIgnore
#JsonManagedReference("user-coordinate")
#Access(value = AccessType.FIELD)
private User user;
}
when I get cars list I get this:
{
"id": 5,
"plateNumber": "aaaaada",
"user": {
"id": 110,
"name": null
}
},
But I want to get this(without user entity!):
{
"id": 5,
"plateNumber": "aaaaada",
},
I have 7 years' experience in PHP (I said it to know I am familiar with how to search and get what I want) but I am a beginner in java spring I searched a lot for the answer all I get is that it's related to Jackson but I don't know how to solve it please help me with details I will appreciate it.
Thank you
you are using #JsonManagedReference("user-coordinate") which overrides #JsonIgnore
JsonManagedReference directs Jackson to serialize the user when serializing car, so if you want user to not be serialized you need to removed it so #JsonIgnore takes place
For anyone had this problem two, I had two dependencies for JsonIgnore I was using:
org.codehaus.jackson.annotate
that was the problem I changed it to:
com.fasterxml.jackson.annotation
And the problem solved

Spring Boot getting empty _embedded array for related entity

Using Spring Boot I'm Having the following abbreviated structure of entities:
#Entity
#Table(name = "item")
#Inheritance(strategy = InheritanceType.JOINED)
public abstract class Item implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", updatable = false)
protected Long id;
...
}
#Entity
#Table(name = "book")
public class Book extends Item implements Serializable {
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "item_author", joinColumns = #JoinColumn(name = "item_id", referencedColumnName = "id"), inverseJoinColumns = #JoinColumn(name = "author_id", referencedColumnName = "id"))
private Set<Author> authors;
}
#Entity
#Table(name = "author")
public class Author implements Serializable {
#Id
#GeneratedValue
private Long id;
#ManyToMany(mappedBy="authors")
private List<Book> books = new ArrayList<Book>();
private String name;
}
My DAOs are just plain simple RestResource interfaces for all entities, like:
#RestResource(path="items", rel="items")
public interface ItemDao extends CrudRepository<Item, Long> {
}
When I query an entity by id, it is all good
GET > http://localhost:8080/shelfventory/authors/1
{
"name" : "Jhonny Cash",
"used" : true,
"_links" : {
"self" : {
"href" : "http://localhost:8080/shelfventory/authors/1"
},
"author" : {
"href" : "http://localhost:8080/shelfventory/authors/1"
},
"books" : {
"href" : "http://localhost:8080/shelfventory/authors/1/books"
}
}
}
But when I try to follow the links for a related object I just get an empty embedded:
GET > http://localhost:8080/shelfventory/authors/1/books
{
"_embedded" : {
"books" : [ ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/shelfventory/authors/1/books"
}
}
}
What am I doing wrong, how to solve it?
Consider adding these two properties to your application.properties to keep your #Entity and schema in sync:
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=true

Resources