Field error in object 'titulo' on field 'status': rejected value [Pendente]; - java

I am trying to learn Spring Framework on the go. During runtime I get following stacktrace:
Validation failed for object='title'. Error count: 1
org.springframework.validation.BindException:
org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'title' on field 'status': rejected value
[Received];
I noticed that the problem is in the status, which is formatted by enum, but I can't any error.
My class Controller:
#Controller
#RequestMapping("/titles")
public class registerTitleController {
#RequestMapping("/title")
public String new() {
return "RegisterTitle";
}
#Autowired
private Titles titles;
#RequestMapping(method=RequestMethod.POST)
public String saveIn(Title title) {
titles.save(title);
return "RegisterTitle";
}
}
My class entity
#Entity
public class Title {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long cod;
private String description;
#DateTimeFormat(pattern="dd/MM/yyyy")
#Temporal(TemporalType.DATE)
private Date dateV;
private BigDecimal val;
#Enumerated(value = EnumType.STRING)
private StatusTitle status;
//other accessor methods
My class enum
public enum StatusTitle {
PENDING("Pending"),
RECEIVED("Received");
private String description;
private StatusTitulo(String descricao){
this.description = description;
}
public String getDescription() {
return description;
}
}
My system work without the status of the attribute.
Can someone point out what is wrong? Your help will be much appreciated.

You probably are sending "Received", but you need to send "RECEIVED" string to properly convert to the ENUM by default.

Related

Serializing Enum to JSON in Java

I have a Java enum where I store different statuses:
public enum BusinessCustomersStatus {
A("active", "Active"),
O("onboarding", "Onboarding"),
NV("not_verified", "Not Verified"),
V("verified", "Verified"),
S("suspended", "Suspended"),
I("inactive", "Inactive");
#Getter
private String shortName;
#JsonValue
#Getter
private String fullName;
BusinessCustomersStatus(String shortName, String fullName) {
this.shortName = shortName;
this.fullName = fullName;
}
// Use the fromStatus method as #JsonCreator
#JsonCreator
public static BusinessCustomersStatus fromStatus(String statusText) {
for (BusinessCustomersStatus status : values()) {
if (status.getShortName().equalsIgnoreCase(statusText)) {
return status;
}
}
throw new UnsupportedOperationException(String.format("Unknown status: '%s'", statusText));
}
}
Full code: https://github.com/rcbandit111/Search_specification_POC/blob/main/src/main/java/org/merchant/database/service/businesscustomers/BusinessCustomersStatus.java
The code works well when I want to get the list of items into pages for the value fullName because I use #JsonValue annotation.
I have a case where I need to get the shortValue for this code:
return businessCustomersService.findById(id).map( businessCustomers -> businessCustomersMapper.toFullDTO(businessCustomers));
Source: https://github.com/rcbandit111/Search_specification_POC/blob/316c97aa5dc34488771ee11fb0dcf6dc1e4303da/src/main/java/org/merchant/service/businesscustomers/BusinessCustomersRestServiceImpl.java#L77
But I get fullValue. Do you know for a single row how I can map the shortValue?
I'd recommend serializing it as an object. This can be done via the #JsonFormat annotation at the class level:
#JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum BusinessCustomersStatus {
A("active", "Active"),
O("onboarding", "Onboarding"),
//...
#Getter
private String shortName;
#Getter
private String fullName;
//...
This will lead to the following result when serializing this enum for BusinessCustomersStatus.A:
{"shortName":"active","fullName":"Active"}
Alternatively, you could define status field as String:
public class BusinessCustomersFullDTO {
private long id;
private String name;
private String businessType;
private String status;
}
and map its value like this:
businessCustomersFullDTO.status(businessCustomers.getStatus().getShortName());

Spring HATEOAS with nested resources and JsonView filtering

I am trying to add HATEOAS links with Resource<>, while also filtering with #JsonView. However, I don't know how to add the links to nested objects.
In the project on on Github, I've expanded on this project (adding in the open pull request to make it work without nested resources), adding the "Character" entity which has a nested User.
When accessing the ~/characters/resource-filtered route, it is expected that the nested User "player" appear with the firstNm and bioDetails fields, and with Spring generated links to itself, but without the userId and lastNm fields.
I have the filtering working correctly, but I cannot find an example of nested resources which fits with the ResourceAssembler paradigm. It appears to be necessary to use a ResourceAssembler to make #JsonView work.
Any help reconciling these two concepts would be appreciated. If you can crack it entirely, consider sending me a pull request.
User.java
//package and imports
...
public class User implements Serializable {
#JsonView(UserView.Detail.class)
private Long userId;
#JsonView({ UserView.Summary.class, CharacterView.Summary.class })
private String bioDetails;
#JsonView({ UserView.Summary.class, CharacterView.Summary.class })
private String firstNm;
#JsonView({ UserView.Detail.class, CharacterView.Detail.class })
private String lastNm;
public User(Long userId, String firstNm, String lastNm) {
this.userId = userId;
this.firstNm = firstNm;
this.lastNm = lastNm;
}
public User(Long userId) {
this.userId = userId;
}
...
// getters and setters
...
}
CharacterModel.java
//package and imports
...
#Entity
public class CharacterModel implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#JsonView(CharacterView.Summary.class)
private Long characterId;
#JsonView(CharacterView.Detail.class)
private String biography;
#JsonView(CharacterView.Summary.class)
private String name;
#JsonView(CharacterView.Summary.class)
private User player;
public CharacterModel(Long characterId, String name, String biography, User player) {
this.characterId = characterId;
this.name = name;
this.biography = biography;
this.player = player;
}
public CharacterModel(Long characterId) {
this.characterId = characterId;
}
...
// getters and setters
...
}
CharacterController.java
//package and imports
...
#RestController
#RequestMapping("/characters")
public class CharacterController {
#Autowired
private CharacterResourceAssembler characterResourceAssembler;
...
#JsonView(CharacterView.Summary.class)
#RequestMapping(value = "/resource-filtered", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseStatus(HttpStatus.OK)
public Resource<CharacterModel> getFilteredCharacterWithResource() {
CharacterModel model = new CharacterModel(1L, "TEST NAME", "TEST BIOGRAPHY", new User(1L, "Fred", "Flintstone"));
return characterResourceAssembler.toResource(model);
}
...
}
CharacterResourceAssembler.java
//package and imports
...
#Component
public class CharacterResourceAssembler implements ResourceAssembler<CharacterModel, Resource<CharacterModel>>{
#Override
public Resource<CharacterModel> toResource(CharacterModel user) {
Resource<CharacterModel> resource = new Resource<CharacterModel>(user);
resource.add(linkTo(CharacterController.class).withSelfRel());
return resource;
}
}

REST web service returns a field that does not exist in the underlying SQL query

When I try to access the following REST service, it returns all data plus a field that does not exist in the "SupplierPayment" entity class "customerId".
#GET
#Produces(MediaType.APPLICATION_JSON)
public List<SupplierPayment> getAllSupplierPaymentsService() {
return (ArrayList<SupplierPayment>) supplierPaymentDao.getAllSupplierPayments();
}
Here is the getAllSupplierPayments() method:
public List<SupplierPayment> getAllSupplierPayments() {
String query = "SELECT * FROM supplierpayment";
return (ArrayList<SupplierPayment>) getJdbcTemplate().query(query,
new BeanPropertyRowMapper<SupplierPayment>(SupplierPayment.class));
}
Here are all the fields in the "SupplierPayment" class:
private Integer supplierPaymentId;
private BigDecimal amount;
private Integer purchaseInvoiceId;
private Integer supplierId;
private Integer paymentMethodId;
private String description;
private Integer checkId;
private Integer fromBankAccountId;
private Integer toBankAccountId;
private String creditCardNo;
private Timestamp created;
private Integer createdBy;
When I debug, I find that the ArrayList of the web service does not return that field, then somehow I find that field in the response.
I tried truncating and dropping the table and adding the columns one after the other. What I found is the field is returned in the response only when I add the column "supplierId" to the table and its value is the same of "supplierId". I think the column "customerId" existed before and I dropped it.
I found that the following getter and setter existed in the SupplierPayment entity class because of the previously existing column in the table:
public Integer getCustomerId() {
return supplierId;
}
public void setCustomerId(Integer customerId) {
this.supplierId = customerId;
}
By removing them, the problem was solved.

Spring Data MongoDB - Audit issue with unique index

If the createdBy references to a document with unique indexes, it fails throwing dup key error.
AbstractDocument.java
public abstract class AbstractDocument implements Auditable<User, String> {
#Version
private Long version;
#Id
private String id;
private User createdBy;
private DateTime createdDate;
private User lastModifiedBy;
private DateTime lastModifiedDate;
}
User.java
#Document(collection = "users")
public class User extends AbstractDocument {
private String name;
private String surname;
#Indexed(unique = true)
private String username;
}
Book.java
#Document(collection = "books")
public Book extends AbstractDocument {
private String title;
}
Now, I have a script (Spring Batch) which initializes the db with some books. The script defines the auditor this way:
#Configuration
#EnableMongoAuditing
public class MongoConfig {
#Bean
public AuditorAware<User> auditorProvider() {
return new AuditorAware<User>() {
#Override
public User getCurrentAuditor() {
User auditor = new User();
auditor.setUsername("init-batch");
auditor.setName("Data initializer");
auditor.setSurname("Data initializer");
return auditor;
}
};
}
}
The script in somewhere does (for each book I need to persist) bookRepository.save(book)
The first book is persisted, but the second one throws:
nested exception is com.mongodb.DuplicateKeyException: Write failed with error code 11000 and error message 'E11000 duplicate key error index: mydb.books.$createdBy.username dup key: { : "init-batch" }'
Why? The unique index is for users collection, why is it checked for audit references?

List of Pojo not getting converted into Json using #ResponseBody

I have controller class as below:
#RequestMapping(value = "/Reporting/FilterAsJson", method = RequestMethod.POST)
public #ResponseBody PagedQueryResult<GetEntitlementOverviewReportResult> filterAsJson(#ModelAttribute GetEntitleReportQuery query, HttpSession session)
{
getEntitlementOverviewFromSession(session).updateFromQuery(query, session);
return queryDispatcher.dispatch(query);}
The POJO class GetEntitlementOverviewReportResult is :
public class GetEntitlementOverviewReportResult
{
private Long id;
private String customerName;
private Long customerId;
private String customerNumber;
private String createdOn;
private String itemCreationDate;
private String licenseStatus;
private String licenseType;
private String licenseStatusCode;
private String licenseID;
private Long requestId;
private String licenseRootID;
private String customerNameCS;
private String customerNumberCS;
// <with getters and setters for the variables>
}
The problem is when all the fields in bean class is being set, proper Json is getting returned as a response. But when only first 6 fields are getting set, the response fails with 500 error in the debugger tool and doesn't return back to the calling ajax method. I get an "internal error" pop up in the browser. What am i missing here? Is is not possible to leave out the other fields whose values are not being fetched? I also tried using #JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) but it doesn't make any difference.

Categories