如何从MySQL中获取一个包含Spring Boot中另一个对象值的属性的对象



在这个对象中,我有几个模型彼此有关系,我试图保存并从数据库中获取,但我似乎无法使其正常工作。该对象包含一个同时包含另一个对象的属性。我的方法是保存到所有相关的模型中,对于这些模型,我也会将当前模型保存到它们中,以便在数据库表中显示关系。

下面是应用程序的模型。

@Entity
@Table(name = "daily_entry")
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class DailyEntry {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "daily_entry_id", unique = true)
private Long id;
@Column(unique = true)
private LocalDate date;
private int weight;
@ManyToOne
@JoinColumn(name="user_id")
private User user;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "daily_macros_id", unique = true)
private DailyMacros dailyMacros;
@OneToMany(mappedBy = "dailyEntry", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Exercise> exercise = new ArrayList<Exercise>();
}
@Entity
@Table(name = "daily_macros")
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class DailyMacros {
@Id
@GeneratedValue
@Column(name = "daily_macros_id")
private Long id;
private int calories;
private int protein;
private int fat;
private int carbs;

@OneToOne(mappedBy = "dailyMacros", cascade = CascadeType.ALL, orphanRemoval = true)
private DailyEntry dailyEntry;
}
@Setter
@Getter
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Table(name= "exercises")
public class Exercise {
@Id
@GeneratedValue
@Column(name = "exercise_id")
private Long id;
private String name;
private int sets;
private int reps;
private int weight;
@ManyToOne
@JoinColumn(name = "daily_entry_id", unique = true)
private DailyEntry dailyEntry;
}
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Long id;
@Column(nullable = false)
private String firstName;
@Column(nullable = false)
private String lastName;
private String role = "user";
private String token;
@Column(unique = true, nullable = false)
protected String username;
@Column(unique = true ,nullable = false)
private String emailAddress;
@Column(nullable = false)
private String password;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "macros_goal_id")
private MacrosGoal macrosGoal;

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<DailyEntry> dailyEntry = new ArrayList<>();
}

我正在尝试将DailyEntry的模型保存到数据库中。用户是DailyEntry的所有者DailyEntry拥有MacroGoal(@OneToOne(和Exercise(@OneToMany(。如何将此模型保存并提取到数据库中?

这就是我尝试过的-对于我的PutMapping,我得到了以下错误:在提交响应后无法调用sendError((

我的GetMapping只返回一个空响应,尽管http状态代码为200

DailyEntryController文件

@RequestMapping(path = "/api/v1/")
@RequiredArgsConstructor
public class DailyEntryController {
@Autowired
DailyEntryService dailyEntryService;
@GetMapping("/getDailyEntry")
public ResponseEntity<DailyEntry> getDailyEntry(@RequestParam("username")  String username, @RequestParam String date) throws ResponseStatusException {
DailyEntry dailyEntry = dailyEntryService.getDailyEntry(username, date);
return new ResponseEntity<>(dailyEntry, HttpStatus.OK);
}
@PutMapping("/addDailyEntry")
public ResponseEntity<DailyEntry> addDailyEntry(@RequestBody DailyEntry dailyEntry, @RequestParam("username") String username) throws ResponseStatusException {
DailyEntry dailyEntryInfo = dailyEntryService.createDailyEntry(dailyEntry, username);
return new ResponseEntity<>( dailyEntryInfo, HttpStatus.OK);
}
}
@Slf4j
@Service
public class DailyEntryServiceImpl implements DailyEntryService {
@Autowired
DailyEntryRepository dailyEntryRepository;
@Autowired
ExerciseRepository exerciseRepository;
@Autowired
UserRepository userRepository;
@Autowired
DailyMacrosRepository dailyMacrosRepository;
@Override
public DailyEntry addExercise(Exercise exercise) {
return null;
}
@Override
public DailyEntry getDailyEntry(String username, String date) {
DailyEntry entry = null;
Optional<User> userFromDatabase = userRepository.findByUsername(username);
User user = userFromDatabase.get();

LocalDate localDate = LocalDate.parse(date);
List<DailyEntry> dailyEntryList =  user.getDailyEntry();

for(DailyEntry e : dailyEntryList) {
if(e.getDate() == localDate){
entry = e;
}
}
return entry;

}

@Override
public DailyEntry createDailyEntry(DailyEntry dailyEntry, String username) {
DailyEntry entry = new DailyEntry();
// Find user
Optional<User> userFromDatabase = userRepository.findByUsername(username);
User user = userFromDatabase.get();
entry.setUser(user);
entry.setDate(LocalDate.parse(dailyEntry.getDate().toString()));
entry.setDailyMacros(dailyEntry.getDailyMacros());
entry.setWeight(dailyEntry.getWeight());
entry.setExercise(dailyEntry.getExercise());
DailyMacros dailyMacros = dailyEntry.getDailyMacros();
dailyMacros.setDailyEntry(entry);
dailyMacrosRepository.save(dailyMacros);
List<Exercise> exercise = dailyEntry.getExercise();
for (Exercise e : exercise) {
e.setDailyEntry(entry);
exerciseRepository.save(e);
}
List<DailyEntry> dailyEntryList = user.getDailyEntry();
dailyEntryList.add(entry);
user.setDailyEntry(dailyEntryList);
userRepository.save(user);
return entry;
}

我也尝试过在存储库中使用Query,但我可能做错了。

您可能应该将@Transactional添加到createDailyEntry。我真的不明白createDailyEntry中发生了什么,但我认为它应该看起来像这样:

@Override
@Transactional
public DailyEntry createDailyEntry(DailyEntry dailyEntry, String username) {
User user = userRepository
.findByUsername(username)
.get();
dailyEntryRepository.save(dailyEntry);
user.getDailyEntry().add(dailyEntry);
dailyEntry.setUser(User);
DailyMacros dailyMacros = dailyEntry.getDailyMacros();
dailyMacros.setDailyEntry(dailyEntry);
dailyMacrosRepository.save(dailyMacros);

dailyEntry.getExcercise()
.forEach( e -> {
e.setDailyEntry(dailyEntry);
exerciseRepository.save(e);
});
// I don't think you need this because user is already managed
// and userFromDatabase.get() will throw an exception
// if the user does not exist.
// userRepository.save(user);
return dailyEntry;
}

我认为getDailyEntry不起作用,因为你使用的是e.getDate() == localDate,它总是false

一种解决方案是向DailyEntryRepository添加一个接受usernamedate:的方法


interface DailyEntryRepository extends JpaRepository<DailyEntry, Long> {
@Query("select de from DailyEntry de where de.user.username = :username and de.date = :localDate")
DailyEntry findByUsernameAndDate(@Param("username") String username, @Param("localDate") LocalDate date);
}
...

@Override
public DailyEntry getDailyEntry(String username, String date) {
LocalDate localDate = LocalDate.parse(date);
return dailyEntryRepository.findByUsernameAndDate(username, localdate);
}

此解决方案将运行查询并仅加载所需的条目。

但是,如果您需要验证用户名,这应该有效:

@Override
public DailyEntry getDailyEntry(String username, String date) {
User user = userRepository
.findByUsername(username)
.get();
LocalDate localDate = LocalDate.parse(date);
for(DailyEntry e : user.getDailyEntry()) {
if (localDate.equals(e.getDate)){
// No need to continue the loop, you've found the entry
return entry;
}
}
// daily entry not found
return null;
}

缺少的另一件事是,在您的模型中,在转换为JSON的过程中没有处理双向关联。解决方案是使用,我最终使用@JsonManagedReference@JsonBackReference,其中您有关联。

相关内容

最新更新