Does Spring Data JPA have any way to count entites using method name resolving?

JavaSpringSpring Data-Jpa

Java Problem Overview


Spring Data JPA supports counting entities using specifications. But does it have any way to count entities using method name resolving? Let's say I want a method countByName to count entities with specific name, just like a method findByName to fetch all entities with specific name.

Java Solutions


Solution 1 - Java

As of Spring Data 1.7.1.RELEASE you can do it with two different ways,

  1. The new way, using query derivation for both count and delete queries. Read this, (Example 5). Example,
    public interface UserRepository extends CrudRepository<User, Integer> {
        long countByName(String name);
    }
  1. The old way, Using @Query annotation.
    Example,
    public interface UserRepository extends CrudRepository<User, Integer> {
        @Query("SELECT COUNT(u) FROM User u WHERE u.name=?1")
        long aMethodNameOrSomething(String name);
    }

or using @Param annotation also,

public interface UserRepository extends CrudRepository<User, Integer> {
    @Query("SELECT COUNT(u) FROM User u WHERE u.name=:name")
    long aMethodNameOrSomething(@Param("name") String name);
}

Check also this so answer.

Solution 2 - Java

As long as you do not use 1.4 version, you can use explicit annotation:

example:

@Query("select count(e) from Product e where e.area.code = ?1")
long countByAreaCode(String code);

Solution 3 - Java

JpaRepository also extends QueryByExampleExecutor. So you don't even need to define custom methods on your interface:

public interface UserRepository extends JpaRepository<User, Long> {
    // no need of custom method
}

And then query like:

User probe = new User();
u.setName = "John";
long count = repo.count(Example.of(probe));

Solution 4 - Java

Working example

@Repository
public interface TenantRepository extends JpaRepository< Tenant, Long > {
    List<Tenant>findByTenantName(String tenantName,Pageable pageRequest);
    long countByTenantName(String tenantName);
}

Calling from DAO layer

@Override
public long countByTenantName(String tenantName) {
	return repository.countByTenantName(tenantName);
}

Solution 5 - Java

This feature has been added in version 1.4 M1

Solution 6 - Java

Apparently it is implemented now DATAJPA-231

Solution 7 - Java

According to Abel, after the version 1.4 (tested in version 1.4.3.RELEASE) is possible doing this way:

public long countByName(String name);

Solution 8 - Java

Thanks you all! Now it's work. DATAJPA-231

It will be nice if was possible to create count…By… methods just like find…By ones. Example:

public interface UserRepository extends JpaRepository<User, Long> {
 
   public Long /*or BigInteger */ countByActiveTrue();
}

Solution 9 - Java

@Autowired
private UserRepository userRepository;

@RequestMapping("/user/count")
private Long getNumberOfUsers(){
    return userRepository.count();
}

Solution 10 - Java

I have only been working with it for a few weeks but I don't believe that this is strictly possible however you should be able to get the same effect with a little more effort; just write the query yourself and annotate the method name. It's probably not much simpler than writing the method yourself but it is cleaner in my opinion.

Edit: it is now possible according to DATAJPA-231

Solution 11 - Java

According to the issue DATAJPA-231 the feature is not implemented yet.

Solution 12 - Java

If anyone wants to get the count based on multiple conditions than here is a sample custom query

@Query("select count(sl) from SlUrl sl where sl.user =?1 And sl.creationDate between ?2 And ?3")
    long countUrlsBetweenDates(User user, Date date1, Date date2);

Solution 13 - Java

In my opinion the other solutions do not answer the question. According to the sentence

> Spring Data JPA supports counting entities using specifications.

he wants to use JPA Specifications with name resolving. All the answers are pointing to the api without specifications.

As long as I know there is no repository implementation with specification and name resolving. The JpaSpecificationExecutor does not support it.

I had the same problem and created a custom repository where I used code like:

CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Long> query = builder.createQuery(Long.class);

Root<S> root = query.from(domainClass);
Path<Object> attribute = root.get(attributeName);
query.select(builder.countDistinct(attribute));

if(spec == null){
    return em.createQuery(query);
}

Predicate predicate = spec.toPredicate(root, query, builder);

if(predicate != null){
    query.where(predicate);
}

return em.createQuery(query);

The variable "attributeName" is a String with the name of the attribute.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionYaoFengView Question on Stackoverflow
Solution 1 - JavaGeorgios SyngouroglouView Answer on Stackoverflow
Solution 2 - JavaRomanView Answer on Stackoverflow
Solution 3 - JavaL. HolandaView Answer on Stackoverflow
Solution 4 - JavaSagar MisalView Answer on Stackoverflow
Solution 5 - JavaAbel PasturView Answer on Stackoverflow
Solution 6 - JavachpopovView Answer on Stackoverflow
Solution 7 - JavaMarcos NunesView Answer on Stackoverflow
Solution 8 - JavaThanongsak ChamungView Answer on Stackoverflow
Solution 9 - JavaБогдан ЛяховецкийView Answer on Stackoverflow
Solution 10 - JavaMark SholundView Answer on Stackoverflow
Solution 11 - JavaOleksandr BondarenkoView Answer on Stackoverflow
Solution 12 - JavaInzimam Tariq ITView Answer on Stackoverflow
Solution 13 - JavaMaddinView Answer on Stackoverflow