我有一些关于在我正在开发的api中使用optionals的问题。
首先,我在本机查询(在jpa存储库中)中使用return选项。这样用可以吗?
我还有一个服务,它检查我的一个实体是否通过它的id退出,如果不是,它抛出一个自定义异常。我不明白的是服务可以返回对象类型,但是jpa查询定义是:optional findbyid(id)???
public BasicTvShowInfo getBasicTvShowInfoById (Integer idTvShow) throws ResourceNotFoundException {
return basicTvShowInfoRepository.findById(idTvShow).orElseThrow(() -> new ResourceNotFoundException(
"The tv show with the id : " + idTvShow + " was not found."));
}
最后,当我想发布实体调用tvshowreminder时,我有一个验证。该实体声明为:
@Entity
@Table(name = "tv_show_reminder")
public class TvShowReminder {
// Attributes
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column (name = "id_tv_show_reminder")
private Integer idTvShowReminder;
@ManyToOne(optional = false)
@JoinColumn(name="id_user")
@NotNull(message = "Provide user {idUser}")
private User user;
@ManyToOne()
@JoinColumn(name= "id_basic_tv_show_info")
private BasicTvShowInfo basicTvShowInfo;
@ManyToOne()
@JoinColumn(name= "id_tv_show_created_by_user")
@OnDelete(action = OnDeleteAction.CASCADE)
private UserTvShow userTvShow;
private Boolean completed;
@Column(name = "current_season")
private Integer currentSeason;
@Column(name = "current_episode")
private Integer currentEpisode;
@Column(name = "personal_rating")
private Integer personalRating;
它有两个嵌套实体,可以为空。基本的vshowinfo和usertvshow。
@Entity
@Table(name = "basic_tv_show_info")
public class BasicTvShowInfo {
@Id
@Column(name = "id_basic_tv_show_info")
@NotNull(message = "Provide id (Integer)")
private Integer id;
@Column(name = "original_name")
@JsonProperty("original_name")
@NotNull(message = "Provide original_name (String)")
private String originalName;
}
@Entity
@Table(name = "tv_show_created_by_user")
public class UserTvShow {
// Attributes
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_tv_show_created_by_user")
private Integer idTvShowCreatedByUser;
@ManyToOne()
@JoinColumn(name= "id_user")
@NotNull(message = "Provide user {idUser}")
private User user;
@Column(name = "name_tv_show")
@NotNull(message = "Provide nameTvShow (String)")
private String nameTvShow;
private String genre;
@Column(name = "production_company")
private String productionCompany;
}
我在服务中有一个验证方法,用于检查:
如果basictvshowinfo和usertvshow都为空。
如果两个对象(basictvshowinfo和usertvshow)都有一个id。
如果登录的用户已经有一个提供了basictvshowinfo id的提醒。
如果登录的用户已经有一个带有usertvshow id的提醒。
在所有这些情况下,我抛出异常。
我如何重构这个工作完美但我想写得更优雅的服务方法?我真的不喜欢用那么多if elseif else和嵌套if。很难遵循规则。
方法如下:
private void validateExistenceOfTvShowReminder(TvShowReminder tvShowReminder) throws ResourceAlreadyExistsException, BusinessLogicValidationFailure, ResourceNotFoundException {
Optional<TvShowReminder> tvShowReminderOptional = Optional.empty();
String messageError = null;
// If both the basic tv show info object and user tv show object ARE PRESENT -> exception
// If the basic tv show info object id already exists in the reminders table -> exception
// If the user tv show info object id already exists in the reminders table -> exception
// If both are null -> exception.
if(tvShowReminder.getBasicTvShowInfo() != null && tvShowReminder.getUserTvShow() != null){
if(tvShowReminder.getBasicTvShowInfo().getId() != null && tvShowReminder.getUserTvShow().getIdTvShowCreatedByUser() != null)
throw new BusinessLogicValidationFailure("You cant have a reminder that point to a tv show from the system and to a tv show created by the user");
} else if(tvShowReminder.getBasicTvShowInfo() != null){
if(tvShowReminder.getBasicTvShowInfo().getId() != null) {
tvShowReminderOptional = tvShowReminderRepository.findByUserIdAndTvShowId(tvShowReminder.getUser().getIdUser(), tvShowReminder.getBasicTvShowInfo().getId());
messageError = "User already created a tv show reminder with the basicTvShowInfo id : " + tvShowReminder.getBasicTvShowInfo().getId();
}
} else if (tvShowReminder.getUserTvShow() != null){
if(tvShowReminder.getUserTvShow().getIdTvShowCreatedByUser() != null) {
// Validate if the user tv show of the reminder actually belongs to the logged user.
if(Optional.ofNullable(userTvShowService.getUserTvShow(tvShowReminder.getUser().getIdUser(), tvShowReminder.getUserTvShow().getIdTvShowCreatedByUser())).isPresent()) {
tvShowReminderOptional = tvShowReminderRepository.findByUserIdAndTvShowCreatedByUserId(tvShowReminder.getUser().getIdUser(), tvShowReminder.getUserTvShow().getIdTvShowCreatedByUser());
messageError = "User already created a tv show reminder with a userTvShow id : " + tvShowReminder.getUserTvShow().getIdTvShowCreatedByUser();
}
}
} else {
messageError = "To create a tv show reminder you have to provided a basicTvShowInfo id OR a userTvShow id";
throw new BusinessLogicValidationFailure(messageError);
}
// Each query findByUserIdAndTvShowId and findByUserIdAndTvShowCreatedByUserId return an optional with the tv show or an empty optional.
// This method will return true if there is a tv show present in the optional OR returns false if is an empty optional (with null value).
if(tvShowReminderOptional.isPresent()){
throw new ResourceAlreadyExistsException(messageError);
}
}
// Repository if it is of any help is:
@Repository
public interface TvShowReminderRepository extends JpaRepository<TvShowReminder, Integer> {
Page<TvShowReminder> findByUser_IdUser(Pageable pageable, Integer idUser);
List<TvShowReminder> findByUser_IdUser(Integer idUser);
@Query(value = "SELECT * FROM tv_show_reminder WHERE id_user = ?1 and id_basic_tv_show_info = ?2", nativeQuery = true)
Optional<TvShowReminder> findByUserIdAndTvShowId(Integer idUser, Integer idBasicTvShowInfo);
@Query(value = "SELECT * FROM tv_show_reminder WHERE id_user = ?1 and id_tv_show_created_by_user = ?2", nativeQuery = true)
Optional<TvShowReminder> findByUserIdAndTvShowCreatedByUserId(Integer idUser, Integer idTvShowCreatedByUser);
@Query(value = "SELECT * FROM tv_show_reminder WHERE id_user = ?1 and id_tv_show_reminder = ?2", nativeQuery = true)
Optional<TvShowReminder> findByIdTvShowReminderAndUserId(Integer idUser, Integer idTvShowReminder);
}
抱歉发了这么长的帖子,提前谢谢你,如果有人能帮我或者指导我正确的做法我会很感激的。
1条答案
按热度按时间y0u0uwnf1#
首先,我在本机查询(在jpa存储库中)中使用return选项。这样用可以吗?
我不明白为什么会不好。
我还有一个服务,它检查我的一个实体是否通过它的id退出,如果不是,它抛出一个自定义异常。我不明白的是服务可以返回对象类型,但是jpa查询定义是:optional findbyid(id)???
这也很好。spring数据只是不想在每次找不到对象时抛出异常,这就是为什么他们使用可选方法的原因。你可以用它做任何你想做的事。
最后,当我想发布实体调用tvshowreminder时,我有一个验证。该实体声明为:
要将验证重构为更可读的形式,我建议您研究jakarta/java ee验证api,也称为bean验证api:https://www.baeldung.com/javax-validation