How to allow entry of only month-year combinations in Java Spring Boot. I need to ensure that the user (Postman client) can enter a record (randomly generated value) for each month of the current year. For example: month: February -> year: 2020 -> generatedValue = random. When the user enters February 2020 again, it throws an exception. I've tried storing the year and month in separate lists to check if the month of that year already exists in the database, but to no avail. First in the RecordService if I want to see if there is no current year entered by the user. For example, if there is no year 2021, then the "if" should add that year to the list so that I can check the month-year combination. It works, but not what I need because the second if always throws a RuntimeException() unless I enter a year that hasn't been entered yet (e.g. there are 2020, 2021, and 2022, but not 2023), so when the user When adding:
{ "month": "March", "year": "2023", "readingTime": "1" }
The code will work because there is no year 2023 in the list, but as soon as they try to enter
{ "month": "May", "year": "2023", "readingTime": "1" }
It won't work because the year already exists, even though it should work because there is no combination for May 2023 in the database. I tried using a boolean to check if the combination exists but that doesn't make any sense to me. So please help :) Here is my code.
RecordController.java
@PostMapping("/{client_id}") public Record add(@PathVariable Long client_id, @RequestBody Record record){ return recordService.add(client_id, record); }
RecordService.java
public Record add(Long client_id, Record record){ ListmonthList = months(); List yearList = years(); Record recordSave = new Record(); recordSave.setId(client_id); recordSave.setYear(record.getYear()); recordSave.setMonth(record.getMonth()); recordSave.setReadingTime(record.getReadingTime()); recordSave.setReadingValue(randomGenerate()); //Does not work if (!yearList.contains(recordSave.getYear())){ yearList.add(recordSave.getYear()); } //Does not work if (monthList.contains(recordSave.getMonth()) && yearList.contains(recordSave.getYear())){ throw new RuntimeException(); } else { recordRepository.save(recordSave); } return null; }
记录.java
@Data @Entity @Table(name = "record") @JsonIgnoreProperties({"hibernateLazyInitializer","handler","device"}) public class Record implements Serializable { @Id @GeneratedValue(strategy= GenerationType.IDENTITY) private Long id; String month; Integer year; String readingTime; Float readingValue; boolean isPresent; }
RandomGenerateValue 和月年函数
public Float randomGenerate(){ int max = 105, min = 14; float random_float = (float)Math.floor(Math.random()*(max-min 1) min); return random_float; } public Listmonths(){ List monthList = new ArrayList<>(); monthList.add("January"); monthList.add("February"); monthList.add("March"); monthList.add("April"); monthList.add("May"); monthList.add("June"); monthList.add("July"); monthList.add("August"); monthList.add("September"); monthList.add("October"); monthList.add("November"); monthList.add("December"); return monthList; } public List years(){ List yearList = new ArrayList<>(); yearList.add(2020); yearList.add(2021); return yearList; }
Keep the year and month together as a single value
Your problem seems to stem from treating the year and month as separate values. Instead, combine them. Think in terms of years and months.
YearMonth
ClassJava contains a class for this concept. It's appropriately named:
YearMonth
and is located in thejava.timepackage.Or use the
Month
enumeration to ensure a valid value.You can use
map
. UseNavigableMap
to keep keys in sorted order.Test whether a value has been entered.
ISO 8601
For text purposes, use the defaultISO 8601format: YYYY-MM
java.timeclasses use ISO 8601 format by default when parsing/generating text.
Assuming that your database does not provide the year and month data type, such a string can be used to store in your database. I don't know of any database that provides this data type. So words are enough.
Please note that when sorting alphabetically, the values will also be sorted chronologically.
Your JSON will look like this: