Spring MVC/Jackson - Nested Entity Deserialization Weirdness - java

I'm having a weird problem with Jackson serialization - I have a Role entity have a nested Permission entity which, in turn, contains a nested Metadata entity. When these entities are retrieved from a Spring MVC #RestController as a list, Jackson serializes the Permission collection into a JSON array. The problem is that sometimes the element placed in this array is just the id of the Permission rather than a serialized representation of the object.
Role.class:
#Entity
#Table(name = "t_db_roles")
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Role.class)
public class Role implements GrantedAuthority {
private final static Logger log = LoggerFactory.getLogger(Permission.class);
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "auto_id")
private int id;
#Column(name = "role", length = 50)
private String name;
#OneToMany(fetch = FetchType.EAGER)
#JoinTable(name = "t_db_role_permissions",
joinColumns = {#JoinColumn(name = "roleid", referencedColumnName = "auto_id")},
inverseJoinColumns = {#JoinColumn(name = "permid", referencedColumnName = "auto_id")}
)
private Set<Permission> permissions;
// getters and setters omitted
}
Permission.class:
#Entity
#Table(name = "t_db_permissions")
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Permission.class)
public class Permission implements GrantedAuthority {
private final static Logger log = LoggerFactory.getLogger(Permission.class);
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "auto_id")
private int id;
#Column(name = "name")
private String name;
#OneToOne(mappedBy = "permission")
private Metadata metadata;
}
Metadata.class
#Entity
#Table(name = "t_report_data")
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Metadata.class)
public class Metadata {
#Id
#Column(name = "id", insertable = false, updatable = false)
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(name = "file_name")
private String fileName;
#Column(name = "human_name")
private String humanName;
#Column(name = "links_to")
#JsonIgnore
private Integer linksTo;
#Column(name = "is_subreport")
#JsonIgnore
private Boolean isSubreport;
#OneToOne(cascade = javax.persistence.CascadeType.ALL, fetch = FetchType.EAGER, optional = false)
#JoinColumn(name = "permid")
private Permission permission;
}
The controller:
#RestController
public class RoleRestController {
private final static Logger log = LoggerFactory.getLogger(PermissionRestController.class);
private RoleService roleService;
private MetadataService metadataService;
#Autowired
public void setRoleService(RoleService service) {
this.roleService = service;
}
#Autowired
public void setMetadataService(ReportMetadataService service) { this.metadataService = service; }
#RequestMapping(value = "/admin/roles/", method = RequestMethod.GET)
public List<Role> getRoles() {
return roleService.getRoles();
}
}
I'm fairly sure that the problem is in serialization - echoing the List<Role> to the console works as expected, but here is the JSON returned (note the first element of the permissions array is an integer rather than a JSON object):
{
"id": 10,
"name": "ROLE_TESTER",
"permissions": [
14,
{
"id": 7,
"name": "ViewDailySettlementSummaryGL",
"metadata": {
"id": 41,
"fileName": "acct_summary_gl.rptdesign",
"humanName": "Daily Settlement Summary GL",
"permission": 7
},
"authority": "ViewDailySettlementSummaryGL"
},
{
"id": 6,
"name": "ViewDailySettlementSummary",
"metadata": {
"id": 24,
"fileName": "acct_summary_os.rptdesign",
"humanName": "Daily Settlement Summary",
"permission": 6
},
"authority": "ViewDailySettlementSummary"
}
],
"authority": "ROLE_TESTER"
}
I can work around this by handling Role serialization manually, but since the SpringMVC/Jackson serialization works for other classes in the project it seems like there must be a problem in these classes that i'm overlooking. Any ideas?

Related

Update the response without null value

I have the following entities provided below,
#Entity(name = "Employee")
#Table(name = "employee")
#Data
#AllArgsConstructor
#NoArgsConstructor
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#CreationTimestamp
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "creation_on" ,updatable = false)
private Date creationOn;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "email")
private String email;
#Column(name = "phoneNumber")
private String phoneNumber;
#Column(name = "age")
private Integer age;
#Column(name = "state")
#Enumerated(EnumType.STRING)
private EmployeeStates employeeState;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "address_id", referencedColumnName = "id")
private Address address;
}
#Data
#AllArgsConstructor
#NoArgsConstructor
#Entity(name = "address")
#Table(name = "address")
public class Address {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
#Column(name = "street")
private String street;
#Column(name = "state")
private String state;
#Column(name = "country")
private String country;
#Column(name = "zip")
private int zip;
#OneToOne(mappedBy = "address")
private Employee employee;
}
The POST call is provided below,
#PostMapping(value = "/create")
public ResponseEntity<Object> createEmployee(#Valid #RequestBody EmployeeDto employeeDto) {
try{
Employee employee = employeeService.createEmployee(employeeDto);
if(employee != null){
return new ResponseEntity<>(employee, new HttpHeaders(), HttpStatus.CREATED);
}
return new ResponseEntity<>(ApiResponseMessage.getGenericApiResponse(Boolean.FALSE, HttpStatus.UNPROCESSABLE_ENTITY,
MessageConstant.EMPLOYEE_NOT_CREATE_MSG), new HttpHeaders(), HttpStatus.UNPROCESSABLE_ENTITY);
}
catch (Exception ex) {
log.error(MessageConstant.INTERNAL_SERVER_ERROR_MSG + ex.getMessage());
return new ResponseEntity<>(ApiResponseMessage.getInternalServerError(), new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
When the response is coming, its below:
{
"id": 2,
"creationOn": "2021-02-27T15:05:23.585+00:00",
"firstName": "string",
"lastName": "string",
"email": "string",
"phoneNumber": "string",
"age": 0,
"employeeState": "ADDED",
"address": {
"id": 3,
"street": "string",
"state": "string",
"country": "string",
"zip": 0,
"employee": null
}
}
How do I not see the "employee": null in the response?
You need to use #JsonInclude(Include.NON_EMPTY) or #JsonInclude(Include.NON_NULL) on your Entity classes.
Like
#Entity(name = "Employee")
#Table(name = "employee")
#Data
#AllArgsConstructor
#NoArgsConstructor
#JsonInclude(Include.NON_EMPTY)
public class Employee {
}
#JsonInclude(Include.NON_EMPTY) -
Value that indicates that only properties with null value,or what is considered empty, are not to be included.Definition of emptiness is data type specific; see belowfor details on actual handling.
#JsonInclude(Include.NON_NULL) - Value that indicates that only properties with non-nullvalues are to be included.
I need to ignore JSON value from the child entity as below:
#OneToOne(mappedBy = "address")
#JsonIgnore
private Employee employee;
This makes all fine.

Class relationship problem does not return some data in JSON

I need return this Json to my project:
{
"data": {
"id": 1,
"username": "renato",
"name": "Renato",
"email": "asdasd#outlook.com",
"roles": [
{
"id": 1,
"name": "ROLE_USER",
"accessList": [
{
"id_access": 1,
"id_role": {
"id_role": 1,
"name": "ROLE_USER",
"authority": "ROLE_USER"
},
"id_program": {
"id_program": 1,
"code_program": "TEST",
"name": "test"
},
"id_view": {
"id_view": 1,
"code_view": "TEST",
"name": "test"
},
"menuYesNo": true,
"accessYesNo": true,
"saveYesNo": true,
"editYesNo": true,
"deleteYesNo": true
}
]
}
]
}
}
But it return this:
{
"data": {
"id": 1,
"username": "renato",
"name": "Renato",
"email": "asdasd#outlook.com",
"roles": [
{
"id": 1,
"name": "ROLE_USER",
"accessList": [
{
"id_access": 1,
"id_role": {
"id_role": 1,
"name": "ROLE_USER",
"authority": "ROLE_USER"
},
"id_program": {},
"id_view": {},
"menuYesNo": true,
"accessYesNo": true,
"saveYesNo": true,
"editYesNo": true,
"deleteYesNo": true
}
]
}
]
}
}
Only classes AccessModel and RoleModel have bidirectional relationship, exists a relationship unidirectional between ProgramModel and ViewModel with AccessModel.
OBS: I mapped UserModel to UserDTO using ModelMapper. Exists RoleModel inside a UserDTO. RoleModel and AccessModel have an #JsonManagedReference and #JsonBackReference respectively, but ProgramModel and ViewModel not.
#Data
#Entity
#Table(schema = "`SCH`", name = "`USER`")
public class UserModel implements UserDetails {
private static final long serialVersionUID = -2195101536379303067L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(table = "USER", name="`ID_USER`", nullable = true)
private Long id_user;
#Column(table = "USER", name="`USERNAME`", nullable = true, length = 50)
private String username;
#Column(table = "USER", name="`PASSWORD`", nullable = true, length = 255)
private String password;
#Column(table = "USER", name="`NAME`", length = 255)
private String name;
#Column(table = "USER", name="`EMAIL`", length = 255)
private String email;
#Column(table = "USER", name="`DATE_EXPERED`", nullable = true)
private LocalDate dateExpered;
#Column(table = "USER", name="`ACCOUNT_ACTIVE`", nullable = true)
private Boolean accountAtive;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(schema = "`SCH`", name = "`USER_ROLE`" ,
joinColumns = #JoinColumn(
name = "`CD_USER`", referencedColumnName ="`ID_USER`"
),
inverseJoinColumns = #JoinColumn(
name = "`CD_ROLE`", referencedColumnName = "`ID_ROLE`"
))
#JsonBackReference
private Collection<RoleModel> roles;
//METHODS USERDETAILS
}
#Data
#Entity
#Table(schema = "`SCH`", name = "`ROLE`")
public class RoleModel implements GrantedAuthority {
private static final long serialVersionUID = -1320143054659054908L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(table = "ROLE", name = "`ID_ROLE`", nullable = true)
private Long id_role;
#Column(table = "ROLE", name = "`NAME`", nullable = true, length = 255)
private String name;
#JsonBackReference
#OneToMany(cascade = CascadeType.ALL, mappedBy = "id_role", fetch = FetchType.LAZY)
private List<AccessModel> accessList;
}
#Data
#Entity
#Table(schema = "`SCH`", name = "`ACCESS`")
public class AccessModel implements Serializable {
private static final long serialVersionUID = -5590889002302223720L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(table = "ACCESS", name = "`ID_ACCESS`", nullable = true)
private Long id_access;
#ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name = "`CD_ROLE`")
#JsonManagedReference
private RoleModel id_role;
#ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name = "`CD_PROGRAM`")
private ProgramModel id_program;
#ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name = "`CD_VIEW`")
private ViewModel id_view;
#Column(table = "ACCESS", name = "`MENU_YES_NO`", nullable = true)
private Boolean menuYesNo;
#Column(table = "ACCESS", name = "`ACCESS_YES_NO`", nullable = true)
private Boolean accessYesNo;
#Column(table = "ACCESS", name = "`SAVE_YES_NO`", nullable = true)
private Boolean saveYesNo;
#Column(table = "ACCESS", name = "`EDIT_YES_NO`", nullable = true)
private Boolean editYesNo;
#Column(table = "ACCESS", name = "`DELETE_YES_NO`", nullable = true)
private Boolean deleteYesNo;
}
#Entity
#Table(name = "`PROGRAM`", schema = "`SCH`")
public class ProgramModel implements Serializable {
private static final long serialVersionUID = -726159076909575803L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(table = "PROGRAM", name = "`ID_PROGRAM`", nullable = true)
private Long id_program;
#Column(table = "PROGRAM", name = "`CODE_PROGRAM`", nullable = true)
private String code_program;
#Column(table = "PROGRAM", name = "`NAME`", nullable = true)
private String name;
#Column(table = "PROGRAM", name = "`ACTIVE`", nullable = true)
private Boolean active;
}
#Entity
#Table(name = "`VIEW`", schema = "`SCH`")
public class ViewModel implements Serializable {
private static final long serialVersionUID = 3900486010030569933L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(table = "VIEW", name = "`ID_VIEW`", nullable = true)
private Long id_view;
#Column(table = "VIEW", name = "`CODE_VIEW`", nullable = true)
private String code_view;
#Column(table = "VIEW", name = "`NAME`", nullable = true)
private String name;
#Column(table = "VIEW", name = "`ACTIVE`", nullable = true)
private Boolean active;
}
I forgot to put #Data in ProgramModel and ViewModel.

how to send only id instead of object in requestbody?

I have two entities. Customer which is mapped in one to many relation with the CustomerDepartment. CustomerDepartment table has a column to store customer Id.
I want to map them in such a way that Customer Object store a list of Customer Department, and the Customer Department stores the id of the customer it belongs to.
The code that is working compels me to send the all the customer details while creating or updating a customer Department.
Is there a way I can only send the id of the customer and it maps itself?
I have tried changing from -
#JsonBackReference
#ManyToOne
#JoinColumn(name = "customer_no", nullable = false)
private Customer customer;
to this -
#JsonBackReference
#ManyToOne(targetEntity = Customer.class)
#JoinColumn(name = "customer_no", nullable = false)
private Integer customer;
which gives me the requestbody I want but it does not work giving the following error -
2019-08-03 04:59:08 ERROR CustomerController:72 - org.springframework.orm.jpa.JpaSystemException: Error accessing field [private java.lang.Integer com.enquero.pulse.entity.Customer.customerNo] by reflection for persistent property [com.enquero.pulse.entity.Customer#customerNo] : 1; nested exception is org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [private java.lang.Integer com.enquero.pulse.entity.Customer.customerNo] by reflection for persistent property [com.enquero.pulse.entity.Customer#customerNo] : 1
Working Code:
Customer:-
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
#DynamicUpdate
#Entity
#Table(name = "customer")
public class Customer extends Auditable<Integer>{
#Id
#Column(name = "customer_no")
private Integer customerNo;
#NotBlank
#Column(name = "customer_name")
private String customerName;
#Column(name = "industry")
private String industry;
#Column(name = "country")
private String country;
#Column(name = "state")
private String state;
#Column(name = "city")
private String city;
#Column(name = "postal_code")
private String postalCode;
#Column(name = "address_line1")
private String addressLine1;
#Column(name = "address_line2")
private String addressLine2;
#Column(name = "address_line3")
private String addressLine3;
#Column(name = "payment_term")
private String paymentTerm;
#Column(name = "customer_segment")
private String customerSegment;
#JsonFormat(pattern="dd-MMM-yyyy")
#Column(name = "engagement_start_on")
private Date engagementStartOn;
#JsonManagedReference
#OneToMany(fetch = FetchType.LAZY, mappedBy = "customer")
private List<CustomerDepartment> customerDepartments;
}
CustomerDepartment:-
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
#DynamicUpdate
#Entity
#Table(name = "customer_department")
public class CustomerDepartment extends Auditable<Integer>{
#Id
#Column(name = "dept_id", updatable = false, nullable = false)
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer deptId;
#Column(name = "dept_name")
private String deptName;
#Column(name = "primary_contact")
private String primaryContact;
#JsonBackReference
#ManyToOne
#JoinColumn(name = "customer_no", nullable = false)
private Customer customer;
}
Current RequestBody:-
{
"createdBy": 0,
"creationDate": "2019-08-02T23:05:33.993Z",
"customer": {
"addressLine1": "string",
"addressLine2": "string",
"addressLine3": "string",
"city": "string",
"country": "string",
"createdBy": 0,
"creationDate": "2019-08-02T23:05:33.993Z",
"customerDepartments": [
null
],
"customerName": "string",
"customerNo": 0,
"customerSegment": "string",
"engagementStartOn": "string",
"industry": "string",
"lastUpdateDate": "2019-08-02T23:05:33.993Z",
"lastUpdatedBy": 0,
"paymentTerm": "string",
"postalCode": "string",
"state": "string"
},
"deptId": 0,
"deptName": "string",
"lastUpdateDate": "2019-08-02T23:05:33.994Z",
"lastUpdatedBy": 0,
"primaryContact": "string"
}
expected requestbody:-
{
"createdBy": 0,
"creationDate": "2019-08-02T23:05:33.993Z",
"customer": 1, //id instead of json
"deptId": 0,
"deptName": "string",
"lastUpdateDate": "2019-08-02T23:05:33.994Z",
"lastUpdatedBy": 0,
"primaryContact": "string"
}
Have you considered a unidirectional #OneToMany: https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#associations?
For example on CustomerDeparment change
#JsonBackReference
#ManyToOne
#JoinColumn(name = "customer_no", nullable = false)
private Customer customer;
}
to
#JsonBackReference
#ManyToOne
#Column(name = "customer_no")
private int customer;
...and on Customer change
#JsonManagedReference
#OneToMany(fetch = FetchType.LAZY, mappedBy = "customer")
private List<CustomerDepartment> customerDepartments;
}
to
#JsonManagedReference
#OneToMany(cascade = CascadeType.ALL)
private List<CustomerDepartment> customerDepartments;
}
As a bit of an aside, I honestly find Hibernate relationships to sometimes be more a hindrance than a help. As an alternative, you may wish to consider dropping the explicit relationship properties, using "regular" columns (#Column(name="customer_no") private int customer') and just writing queries in your repo classes (ex. findByCustomerNo(int customNumber)) to meet your requirements.

Can't save entity in hibernate

I have created simple CRUD service. With 4 entities: Customer, Provider, Product, Deal.
Customer and Provider entities has composed id AppId with the following structure:
#Getter
#Setter
#Embeddable
#NoArgsConstructor
public class AppId implements Serializable {
private String app;
private String id;
//...
}
Here is business logic I want:
Providers entity cascades and creates Product entities.
When the customer makes deal with provider I need to create entity Deal, which doesn't cascade any other entities.
It just has fields which refer to provider, customer and product of the deal.
I created some providers and customers.
Then I tried to create deal, but I got fields customer and provider null.
Here are my entities definitions:
Provider:
#Entity
#Getter
#Setter
#ToString
#NoArgsConstructor
#Table(name = "provider")
public class Provider implements Serializable {
#EmbeddedId
#Column(name = "appid")
private AppId appId;
#Column(name = "name")
private String name;
#Column(name = "firstname")
private String firstName;
#Column(name = "lastname")
private String lastName;
#Column(name = "latitude")
private float latitude;
#Column(name = "longitude")
private float longitude;
#Column(name = "work_date")
private Date workDate;
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "provider_product"
, joinColumns = {
#JoinColumn(name = "provider_app"),
#JoinColumn(name = "provider_id")
}
, inverseJoinColumns = #JoinColumn(name="product_id"))
private Set<Product> products;
#OneToMany(cascade = CascadeType.ALL)
#JoinColumns({
#JoinColumn(name = "app", referencedColumnName = "app", updatable = false, insertable = false),
#JoinColumn(name = "id", referencedColumnName = "id", updatable = false, insertable = false)
})
private List<Deal> dealList = new ArrayList<>();
}
Customer:
#Entity
#Getter
#Setter
#ToString
#NoArgsConstructor
#Table(name = "customer")
public class Customer implements Serializable {
#EmbeddedId
#Column(name = "appid")
private AppId appId;
#Column(name = "firstname")
private String firstName;
#Column(name = "lastname")
private String lastName;
public Customer(AppId appId, String firstName, String lastName) {
this.appId = appId;
this.firstName = firstName;
this.lastName = lastName;
}
}
Product:
#Entity
#Getter
#Setter
#ToString
#NoArgsConstructor
#Table(name = "product")
public class Product implements Serializable {
#Id
#GeneratedValue
private long id;
#Column(name = "name")
private String name;
#Column(name = "cost")
private long cost;
}
Deal:
#Entity
#Getter
#Setter
#ToString
#NoArgsConstructor
#Table(name = "deal")
public class Deal implements Serializable {
#Id
#GeneratedValue
private long id;
#ManyToOne
#JoinColumns({
#JoinColumn(name = "provider_app", referencedColumnName = "app", insertable = false, updatable = false),
#JoinColumn(name = "provider_id", referencedColumnName = "id", insertable = false, updatable = false)
})
private Provider provider;
#ManyToOne
#JoinColumns({
#JoinColumn(name = "customer_app", insertable = false, updatable = false),
#JoinColumn(name = "customer_id", insertable = false, updatable = false)
})
private Customer customer;
#ManyToMany
#JoinTable(name = "deal_product"
, joinColumns = #JoinColumn(name="deal_id", insertable = false, updatable = false)
, inverseJoinColumns = #JoinColumn(name="product_id", insertable = false, updatable = false))
private Set<Product> product;
// deal is complete when provider entered deal id
#Column(name = "closed")
private boolean closed = false;
}
By removing insertable = false for customer and provider fields in the Deal entity, everything works fine.
{
"id": 5,
"provider": {
"appId": {
"app": "vk",
"id": "123"
},
"name": null,
"firstName": null,
"lastName": null,
"latitude": 0,
"longitude": 0,
"workDate": null,
"products": null,
"dealList": []
},
"customer": {
"appId": {
"app": "vk",
"id": "123"
},
"firstName": null,
"lastName": null
},
"product": [
{
"id": 2,
"name": "Temp",
"cost": 100
}
],
"closed": false
}
I could get the following response.
insertable = false on a field means when you are saving the entity you won't be saving the value for that field and will set the field explicitly somewhere.
insertable = true doesn't mean you will create a new Customer or Provider, that is handled by CascadeType

How to JSON returning child object details using JPA and Springboot

I'm using Springboot + JPA to do a restful backend, I have two entities and I need to get a JSON response with child object details like this:
{
"mensagens": [
{
"id": "2",
"origem_id": "1",
"destino_id": "2",
"assunto": "hello",
"corpo": "hi, how are you?",
"origem": {
"id": "1",
"nome_completo": "Leonard",
"apelido": "leo"
},
"destino": {
"id": "2",
"nome_completo": "Mark",
"apelido": "mark"
}
}
]
}
Can anyone help me?
======================================================================================================================================================
My classes are below:
This is my Entity Contact:
#Entity
#Table(schema="schema")
public class Contact {
#Id
#GeneratedValue
#Column(name = "contact_id")
private long id;
#Column(name = "nome_completo", nullable = true)
#JsonProperty(value = "nome_completo")
private String nomeCompleto;
#Column(name = "apelido", nullable = true)
private String apelido;
#OneToMany(mappedBy = "origemId", cascade = CascadeType.ALL)
private List<Message> msgOrigem;
#OneToMany(mappedBy = "destinoId", cascade = CascadeType.ALL)
private List<Message> msgDestino;
// getters and setters
This is my Entity Message
#Entity
#Table(name = "message", schema = "schema")
public class Message {
#Id
#GeneratedValue
#Column(name = "msg_id")
private long id;
#Column(name = "origem_id")
private long origemId;
#Column(name = "destino_id")
private long destinoId;
#Column(name = "assunto")
private String assunto;
#Column(name = "corpo")
private String corpo;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "contactId")
private Contact contact;
// getters and setters
My repository:
#RestResource(exported = false)
public interface MessageRepository extends JpaRepository<Message, Long> {}
My Class Messages:
public class Messages {
private List<Message> mensagens;
public List<Message> getMensagens() {
return mensagens;
}
public void setMensagens(List<Message> mensagens) {
this.mensagens = mensagens;
}
}
my rest controller:
#RestController
#RequestMapping(path = "/sdm/mensageiro/mensagens")
public class ListMessagesController {
#Autowired
private MessageRepository repository;
#GetMapping
public Messages findAllMessages() {
Messages c = new Messages();
c.setMensagens(repository.findAll());
return c;
}
}
This is the class that run the springboot applcation:
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
I use the postman to retrive from Mysql data and now my result JSON is like below:
{
"mensagens": [
{
"id": 2,
"origemId": 1,
"destinoId": 2,
"assunto": "Hello",
"corpo": "hi, how are you?"
}
]
}
Should update fetch type to EAGER in order to when getting the list persiste, here is things that you need to update:
#OneToMany(mappedBy = "origemId", cascade = CascadeType.ALL, fetch=FetchType.EAGER)
private List<Message> msgOrigem;
#OneToMany(mappedBy = "destinoId", cascade = CascadeType.ALL, fetch=FetchType.EAGER)
private List<Message> msgDestino;
And ignore Contact in order not to display contact again because you will have a recursive error.
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "contactId")
#JsonIgnore
private Contact contact;

Categories