我有以下服务,在一个项目中有一个实现:
@Service
public class ProjectServiceImpl implements ProjectService {
@Autowired
private ProjectRepository projectRepository;
@Autowired
private ProjectAdaptor projectAdaptor;
@Override
public List<Project> getAll() {
return projectRepository.findAll();
}
@Override
public List<Project> getAllProjects(Long companyId) {
return projectRepository.getAll().stream()
.filter(project -> project.getId() == companyId).findAny().orElse(null);
}
@Override
public Project save(Project project) {
return projectRepository.save(project);
}
@Override
public List<ProjectDTO> findAllProducts() {
List<Project> project = projectRepository.findAll();
return projectAdaptor.databaseModelToUiDtoList(project);
}
}
其中有一个方法 getAll():
@Override
public List<Project> getAll() {
return projectRepository.findAll();
}
并相应地getAllProjects():
@Override
public List<Project> getAllProjects(Long companyId) {
return projectRepository
.getAll()
.stream()
.filter(project -> project.getId() == companyId)
.findAny()
.orElse(null);
}
在这方面,问题是如何重构上述方法,它重现了与类型相关的编译错误Object:
无法解析中的方法
getId。Object
我的实体Project具有以下结构:
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity(name = "project_entity")
@Table(name = "projects")
public class Project {
public Project(ProjectDTO projectDTO) {
this.name = projectDTO.getName();
this.abbreviation = projectDTO.getAbbreviation();
this.customer = projectDTO.getCustomer();
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "project_id")
private Integer id;
private String name;
private String abbreviation;
private String customer;
}
我是否需要Lombok在实体上添加额外的注释来解决这个问题,或者有没有办法以更正确的方式将两种方法合二为一?
我将非常感谢你在这件事上的帮助。

我还想指出,返回 null 不是好的做法,您可以将其全部包装在
Optional<T>,并且findAny()在方法中它也getAllProjects()意味着从 Optional 包装器中的流返回一个值,但您的方法返回List<Project>。为避免您描述的问题:
getAll()在通话中替换为findAll(). 此方法返回一个对象列表Project而不是Object。或者转换为
Projectlambda 表达式中的类型.filter(((Project)project) -> project.getId() == companyId)当然,第一种方法更可取。如果对你有帮助,请标记我的答案。
我建议你再仔细考虑一下——是否值得在内存中进行过滤。如果您严格保证它
projectRepository.findAll()永远不会返回大量对象并且很少被调用,那么您使用 Stream 的内存过滤方法是合适的。否则,在存储库中创建一个单独的方法,该方法可以按 companyId 过滤项目并在服务内部调用它(或者您可以在存储库级别创建一个接受通用过滤器的方法,例如,通过 Criteria API)。另一个重要的一点是,如果您的方法返回一个列表,那么它永远不应该返回 null。这是非常糟糕的做法。如果您没有对象 - 只需返回一个空列表。
目前尚不清楚方法
projectRepository.findAll()和projectRepository.getAll(). 根据他们的名字,结论是他们做同样的事情。在这种情况下,您有代码重复。如果他们做不同的事情,那么重命名其中一个方法,以便立即清楚。在服务级别进行交易是可取的。
按照方法命名的顺序。如果在存储库级别该方法被称为 findAll(),那么在服务级别它的包装器方法应该被完全相同地调用。