Solución:
¿Por qué no usar el @Query
¿anotación?
@Query("select p.id from #{#entityName} p")
List<Long> getAllIds();
La única desventaja que veo es cuando el atributo id
cambios, pero dado que este es un nombre muy común y es poco probable que cambie (id = clave principal), debería estar bien.
Esto ahora es compatible con Spring Data usando proyecciones:
interface SparseCustomer {
String getId();
String getName();
}
Que en tu Customer
repositorio
List<SparseCustomer> findAll(Specification<Customer> spec);
EDITAR:
Como señaló Radouane, las proyecciones ROUFID con especificaciones actualmente no funcionan debido a un error.
Pero puede usar la biblioteca de especificación con proyección que soluciona esta deficiencia de Spring Data Jpa.
Resolví el problema.
(Como resultado, tendremos un objeto de cliente escaso solo con id y nombre)
Defina su propio repositorio:
public interface SparseCustomerRepository {
List<Customer> findAllWithNameOnly(Specification<Customer> spec);
}
Y una implementación (recuerde el sufijo – Impl por defecto)
@Service
public class SparseCustomerRepositoryImpl implements SparseCustomerRepository {
private final EntityManager entityManager;
@Autowired
public SparseCustomerRepositoryImpl(EntityManager entityManager) {
this.entityManager = entityManager;
}
@Override
public List<Customer> findAllWithNameOnly(Specification<Customer> spec) {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Tuple> tupleQuery = criteriaBuilder.createTupleQuery();
Root<Customer> root = tupleQuery.from(Customer.class);
tupleQuery.multiselect(getSelection(root, Customer_.id),
getSelection(root, Customer_.name));
if (spec != null) {
tupleQuery.where(spec.toPredicate(root, tupleQuery, criteriaBuilder));
}
List<Tuple> CustomerNames = entityManager.createQuery(tupleQuery).getResultList();
return createEntitiesFromTuples(CustomerNames);
}
private Selection<?> getSelection(Root<Customer> root,
SingularAttribute<Customer, ?> attribute) {
return root.get(attribute).alias(attribute.getName());
}
private List<Customer> createEntitiesFromTuples(List<Tuple> CustomerNames) {
List<Customer> customers = new ArrayList<>();
for (Tuple customer : CustomerNames) {
Customer c = new Customer();
c.setId(customer.get(Customer_.id.getName(), Long.class));
c.setName(customer.get(Customer_.name.getName(), String.class));
c.add(customer);
}
return customers;
}
}
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)