3

So I encountered this issue with updating an entity in DB. while Passing a whole entity and updating only specific fields it treats untouched fields as null, as a result I get an exception since those fields are @Not-Null,

I have tried looking for similar problems but could not fix my problem.

Company ENTITY:

@Entity @Table (name = "companies") @Data @ToString(exclude = "perfumes") @AllArgsConstructor @NoArgsConstructor @Builder public class Company { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; @NotNull private String name; @NotNull @Email(message = "Wrong input. please enter a VALID email address") private String email; @NotNull @Size(min = 4, max = 14, message = "Password range must be between 4 - 14 digits") private String password; @NotNull @Enumerated(EnumType.STRING) private Country country; @Singular @OneToMany(mappedBy = "company", fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List<Perfume> perfumes = new ArrayList<>(); } 

Most fields are @NotNull for creation, however, I need to update the entity, sometimes only specific fields.

Service:

@Override public String updateCompany(int id, Company company) throws DoesNotExistException { if(!companyRepository.existsById(id)) { throw new DoesNotExistException(id); } companyRepository.saveAndFlush(company); return company.getName() + " has been UPDATED"; } 

as you can see an ENTITY has been passed which causes rest of attributes to be automatically null if not modified.

Controller:

 @PutMapping("/updateCompany/{id}") @ResponseStatus(HttpStatus.ACCEPTED) public String updateCompany(@PathVariable int id, @RequestBody Company company) throws DoesNotExistException { return admin.updateCompany(id,company); } 

EXCEPTION:

Validation failed for classes [com.golden.scent.beans.Company] during update time for groups [javax.validation.groups.Default, ] List of constraint violations:[ ConstraintViolationImpl{interpolatedMessage='must not be null', propertyPath=password, rootBeanClass=class com.golden.scent.beans.Company, messageTemplate='{javax.validation.constraints.NotNull.message}'} ] 

Thanks.

2
  • The next question is if you're updating this entity, it implies it is already coming from the database. If so, this implies that these non nullable fields should have non null values. What is responsible for nulling out certain of the fields? Commented Nov 21, 2021 at 18:46
  • @TimBiegeleisen passing the whole entity is responsible for that. since JPA automatically assigns null values to unmodified attributes. is there a way to tell it to leave it as it is if un-touched? sorry still new to this. Commented Nov 21, 2021 at 19:02

1 Answer 1

3

The controller is binding the values you pass in to a new Company entity. The new entity is not attached to the persistence context, it does not have the state of the pre-existing entity. When you save it JPA thinks you want to null out all the fields you don't have values for.

Instead, you could have the controller bind its arguments to a DTO. Then in the service you look up the existing Customer, using findById, and copy the fields you want updated from the DTO to the entity. Then call saveAndFlush passing in the updated entity.

It looks like there's an improvement over the DTO, you can use aJsonPatch to hold the updates passed in, see https://www.baeldung.com/spring-rest-json-patch. The patch method seems like a better match for what you're doing anyway.

On the server the important thing is to look up the existing entity so that you have an entity that is attached to the persistence context and has all its fields current.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.