YaoFeng
YaoFeng

Reputation: 1949

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

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.

Upvotes: 194

Views: 405859

Answers (13)

Maddin
Maddin

Reputation: 11

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.

Upvotes: 0

Inzimam Tariq IT
Inzimam Tariq IT

Reputation: 6758

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);

Upvotes: 2

Georgios Syngouroglou
Georgios Syngouroglou

Reputation: 19944

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.

Upvotes: 353

Roman
Roman

Reputation: 3299

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);

Upvotes: 38

Mark Sholund
Mark Sholund

Reputation: 1312

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

Upvotes: 1

@Autowired
private UserRepository userRepository;

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

Upvotes: 4

Sagar Misal
Sagar Misal

Reputation: 145

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);
}

Upvotes: 13

L. Holanda
L. Holanda

Reputation: 4631

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));

Upvotes: 20

Thanongsak Chamung
Thanongsak Chamung

Reputation: 311

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();
}

Upvotes: 4

Marcos Nunes
Marcos Nunes

Reputation: 1355

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);

Upvotes: 6

chpopov
chpopov

Reputation: 141

Apparently it is implemented now DATAJPA-231

Upvotes: 5

Abel Pastur
Abel Pastur

Reputation: 1965

This feature has been added in version 1.4 M1

Upvotes: 11

Oleksandr Bondarenko
Oleksandr Bondarenko

Reputation: 2018

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

Upvotes: 1

Related Questions