【发布时间】:2020-11-02 01:32:18
【问题描述】:
我正在使用带有 SDR、HATEOAS、Hibernate 的 Spring Boot 2.3.1。在我的项目中,我通过 Spring Data REST 公开了存储库。 我已经在其他项目中使用了 SDR,但在这个项目中,我的一个控制器有一个奇怪的问题。事实上,如果我在这个控制器中添加一些自定义端点,相关实体的所有默认端点都将被隐藏并且不再可用。
让我解释得更好。我有这个实体:
@EntityListeners(TenantListener.class)
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
public class Tenant extends AbstractEntity {
@Enumerated(value = EnumType.STRING)
@Column(nullable = false, updatable = false)
private TenantType type;
@NotBlank
@Column(nullable = false)
private String fullName;
@NotBlank
@Column(nullable = false)
private String lastName;
@NotBlank
@Column(nullable = false)
private String firstName;
@Username
@Size(min = 4, max = 16)
@Column(nullable = false, unique = true)
@ColumnTransformer(write = "LOWER(?)")
private String tenantId;
//other fields
这是存储库:
@Transactional
@IsManagementUser
public interface TenantRepository extends JpaRepository<Tenant, Long>, JpaSpecificationExecutor {
@Caching(evict = {
@CacheEvict(value = "tenants", allEntries = true),
@CacheEvict(value = "tenants#id", allEntries = true),
@CacheEvict(value = "tenants#sid", allEntries = true),
@CacheEvict(value = "tenants#exists", allEntries = true),
})
@Override
<S extends Tenant> S save(S s);
@Caching(evict = {
@CacheEvict(value = "tenants", allEntries = true),
@CacheEvict(value = "tenants#id", allEntries = true),
@CacheEvict(value = "tenants#sid", allEntries = true),
@CacheEvict(value = "tenants#exists", allEntries = true),
})
@Override
void deleteById(Long aLong);
@Caching(evict = {
@CacheEvict(value = "tenants", allEntries = true),
@CacheEvict(value = "tenants#id", allEntries = true),
@CacheEvict(value = "tenants#sid", allEntries = true),
@CacheEvict(value = "tenants#exists", allEntries = true),
})
@Modifying
void deleteByTenantId(String tenantId);
@Cacheable(cacheNames = "tenants#id")
Optional<Tenant> findByTenantId(@Param("tenantId") String tenantId);
@Cacheable(cacheNames = "tenants#sid")
@Query("SELECT sid FROM Tenant t WHERE t.tenantId=:tenantId")
String findSidByTenantId(@Param("tenantId") String tenantId);
@Cacheable(cacheNames = "tenants#exists")
@Query("SELECT case WHEN (COUNT(*) > 0) THEN true ELSE false end FROM Tenant WHERE tenantId=:tenantId")
boolean existsTenantId(@Param("tenantId") String tenantId);
@Caching(evict = {
@CacheEvict(value = "tenants", allEntries = true),
@CacheEvict(value = "tenants#id", allEntries = true),
@CacheEvict(value = "tenants#exists", allEntries = true),
})
@Modifying
@Query("UPDATE Tenant t SET t.verified=:verified, t.version=t.version+1, t.lastModifiedDate=UTC_TIMESTAMP() WHERE t.tenantId=:tenantId")
void setVerified(@Param("tenantId") String tenantId, @Param("verified") boolean verified);
@Caching(evict = {
@CacheEvict(value = "tenants", allEntries = true),
@CacheEvict(value = "tenants#id", allEntries = true),
@CacheEvict(value = "tenants#exists", allEntries = true),
})
@Modifying
@Query("UPDATE Tenant t SET t.enabled=:enabled, t.version=t.version+1, t.lastModifiedDate=UTC_TIMESTAMP() WHERE t.tenantId=:tenantId")
void setEnabled(@Param("tenantId") String tenantId, @Param("enabled") boolean enabled);
}
这是 REST 控制器:
@RepositoryRestController
@RequestMapping(path = "/api/v1")
@PreAuthorize("isAuthenticated()")
public class TenantController {
@Autowired
private LocalValidatorFactoryBean validator;
@Autowired
private TenantRepository tenantRepository;
@Autowired
private DbmsManager dbmsManager;
@Autowired
private PagedResourcesAssembler pagedResourcesAssembler;
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.addValidators(validator);
}
@IsManagementUser
@DeleteMapping(path = "/tenants/{id}")
public ResponseEntity<?> deleteTenant(@PathVariable("id") Long id) {
Optional<Tenant> optionalTenant = tenantRepository.findById(id);
if (optionalTenant.isPresent()) {
dbmsManager.dropTenant(optionalTenant.get().getTenantId());
}
return ResponseEntity.noContent().build();
}
}
如果我调用端点GET http://localhost/api/v1/tenants,我会得到完整的租户列表。如果我尝试调用任何其他方法,例如 GET http://localhost/api/v1/tenants/1 或 PATCH http://localhost/api/v1/tenants/1,我会在控制台中收到警告:
12/07/2020 21:51:01,440 WARN http-nio-9999-exec-2 PageNotFound:209 - Request method 'GET' not supported
如果我在我的 TenantController 中注释掉所有端点,那么一切正常。看来,无论我在控制器中创建什么端点,都会隐藏所有其他 SDR 默认端点。
这只是发生在这个实体和这个控制器上,但我没有看到任何特别的东西。任何提示都非常感谢,以便了解问题所在。
【问题讨论】:
标签: java spring spring-mvc spring-data spring-data-rest