我有一个带有实体 Person 的 Spring Boot 应用程序,其中包含该人的事件列表。
像这样。
public class Person....
private Long id;
private String name;
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "person_events", joinColumns = @JoinColumn(name = "person_id"))
private List<String> personEvents = new ArrayList<>();
现在,当我选择时,我想将结果选择到这样的 dto 中。
@Query("""
select new com.....dtos.PersonDto(p.name, p.events) from Person p
where p.name = (:name)
""")
Set<PersonDto> findPersonsByName(String name);
我的存储库失败,因为它无法生成 sql。我怎样才能做到这一点?
答案 0 :(得分:0)
您正在做的一些事情可以改进,例如:
您可以使用 interface
投影代替构造函数选择
Set<PersonDto> findPersonsByName(String name);
由于您对单个项目进行选择,因此结果将是单个对象。 所以请把它改成
PersonDTO findPersonsByName(String name);
请在下面找到我的完整答案:
package com.example.demo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@RestController
@RequestMapping("/person")
public class PersonController {
private final PersonService personService;
@Autowired
public PersonController(PersonService personService) {
this.personService = personService;
}
@GetMapping
public Iterable<Person> list() {
return personService.list();
}
@PostMapping
public Person create(@RequestBody Person car) {
return personService.save(car);
}
@GetMapping(path = "/by")
public PersonDTO getPersonByName(@RequestParam(value = "name") String name) {
return personService.findPersonByName(name);
}
}
@Getter
@Setter
@ToString
@Entity
class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "person_events", joinColumns = @JoinColumn(name = "person_id"))
private List<String> personEvents = new ArrayList<>();
}
@Service
class PersonService {
private final PersonRepository personRepository;
@Autowired
PersonService(PersonRepository personRepository) {
this.personRepository = personRepository;
}
@Transactional
public Person save(Person person) {
return personRepository.save(person);
}
@Transactional(readOnly = true)
public Iterable<Person> list() {
return personRepository.findAll();
}
@Transactional(readOnly = true)
public PersonDTO findPersonByName(String name) {
return personRepository.findPersonsByName(name);
}
}
interface PersonDTO {
String getName();
Collection<String> getPersonEvents();
}
@Repository
interface PersonRepository extends JpaRepository<Person, Integer> {
PersonDTO findPersonsByName(String name);
}