Issue
I'm trying to create some default values for some field inside entity.
This is my Entity:
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Data
@Table(name="users")
public class User extends BaseEntity{
@Column(name="email")
private String email;
@Column(name="password")
private String password;
@Column(name="tokens", insertable = false)
@ElementCollection(targetClass=String.class)
private List<String> tokens;
@Column(name="firstName")
private String firstName;
@Column(name="lastName")
private String lastName;
@Column(name="permission", insertable = false, columnDefinition="tinyint(1) default 0")
private Integer permission;
@Column(name="deleted", columnDefinition = "boolean default false", insertable = false)
private boolean deleted;
@Column(name="expirationDate", insertable = false)
@CreationTimestamp
@Temporal(TemporalType.TIMESTAMP)
private Date expirationDate;
}
The fields that I want to receive from the client is:
email, password, firstName, lastName
.
This is my route that receive the input and persist it:
@PostMapping("/createUser")
public ResponseEntity<User> createUser(@RequestBody User user) {
try{
return ResponseEntity.ok()
.body(userService.addUser(user));
} catch (CustomException e){
throw new CustomException(e.getMessage());
}
}
Via the annotation @RequestBody
I am able to send an json to the server:
{
"email": "[email protected]",
"password": "123456",
"firstName": "Itzik",
"lastName": "Barabie",
"permission": 4,
"deleted": "true"
}
And it's seem to be that the user can specify it's own values for fields permission
and deleted
, Which I have annotate then with insertable = false
.
This is the returned object.
{
"userId": 6,
"createDate": "2022-02-14T22:38:21.892+00:00",
"updatedDate": "2022-02-14T22:38:21.892+00:00",
"deleted": true,
"email": "[email protected]",
"password": "85784496ddc1811f5b71ee2a2797924139c550f784bd72753bc4daa9e731e148a0e57067038b5d4a82e2cecf910505ad06ec49a12d777a81f471ef81f8bae9ef",
"tokens": null,
"firstName": "Itzik",
"lastName": "Barabie",
"permission": 4,
"expirationDate": "2022-02-14T22:38:21.892+00:00"
}
This is an expected behavior? Or I'm missing something..
I have understand that insertable = false
and updateable = false
should block any attempt for insert or update manually.
Thanks!
Solution
If you just want to restrict the API from accessing the fields that are only meant for internal use in the service layer such as permission/delete, then you are better off using
@JsonIgnore
or
@JsonProperty
annotations instead of @Insertable or @Updatable. This will hide the fields from the API.
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Data
@Table(name="users")
public class User extends BaseEntity{
@Column(name="email")
private String email;
@Column(name="password")
private String password;
@Column(name="tokens", insertable = false)
@ElementCollection(targetClass=String.class)
private List<String> tokens;
@Column(name="firstName")
private String firstName;
@Column(name="lastName")
private String lastName;
@JsonIgnore
@Column(name="permission", columnDefinition="tinyint(1) default 0")
private Integer permission;
@JsonIgnore
@Column(name="deleted", columnDefinition = "boolean default false")
private boolean deleted;
@Column(name="expirationDate", insertable = false)
@CreationTimestamp
@Temporal(TemporalType.TIMESTAMP)
private Date expirationDate;
}
You can also choose to make the fields optionally hide during either a read or write. For example
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
will show the value in API but not allow it to be written.
Answered By - Monish Sen
Answer Checked By - Willingham (JavaFixing Volunteer)