Implementing Methods to Get and Count Entities

Service Builder generates findBy* methods and countBy* methods in your *Persistence classes based on your service.xml file’s finders. You can leverage finder methods in your local services to get and count entities.

  • Getters: get* methods return entity instances matching criteria.
  • Counters: get*Count methods return the number of instances matching criteria

Start with getting entities that match criteria.

Getter Methods

The findByPrimaryKey methods and findBy* methods search for and return entity instances based on criteria. Your local service implementation must only wrap calls to the finder methods that get what you want.

Here’s how to create a method that gets an entity based on an ID (primary key):

  1. Create a method using this format:

    public [ENTITY] get[ENTITY_NAME](long id) {
        return [ENTITY]Persistence.findByPrimaryKey(id);
  2. Replace [ENTITY] and [ENTITY_NAME] with the respective entity type and entity name (or nickname).

  3. Run Service Builder to propagate the method to your local service interface.

Here’s how to get entities based on criteria:

  1. Identify the criteria for finding the entity instance(s).

  2. If there is no finder element for the criteria, create one for it and run Service Builder.

  3. Determine the *Persistence class findBy* method you want to call. Depending on your finder element columns, Service Builder might overload the method to include these parameters:

    • int start and int end parameters for specifying a range of entities.
    • com.liferay.portal.kernel.util.OrderByComparator orderByComparator parameter for arranging the matching entities.
  4. Specify your get* method signature, making sure to account for the *Persistence class findBy* method parameters you must satisfy. Use this method format:

    public List<[ENTITY]> get[DESCRIBE_THE_ENTITIES](...) {

    Replace [ENTITY] with the entity type. Replace [DESCRIBE_THE_ENTITIES] with a descriptive name for the entities you’re getting.

  5. Call the *Persistence class findBy* method and return the list of matching entities.

  6. Run Service Builder.

For example, getGuestbookEntries from GuestbookEntryLocalServiceImpl returns a range of GuestbookEntrys associated with a Group primary key:

public List<GuestbookEntry> getGuestbookEntries(long groupId, long guestbookId) {
    return guestbookEntryPersistence.findByG_G(groupId, guestbookId);

Now you know how to leverage finder methods to get entities. Methods that count entities are next.

Counter Methods

Counting entities is just as easy as getting them. Your *Persistence class countBy* methods do all the work. Service Builder generates countBy* methods based on each finder and its columns.

  1. Identify the criteria for entity instances you’re counting and determine the *Persistence class countBy* method that satisfies the criteria.

  2. Create a get*Count method signature following this format:

    public int get[DESCRIBE_THE_ENTITIES]Count(...) {

    Replace [DESCRIBE_THE_ENTITIES] with a descriptive name for the entities you’re counting.

  3. Call the *Persistence class’ countBy method and return the value. For example, the method getEntriesCount from GuestbookEntryLocalServiceImpl returns the number of GuestbookEntrys that are associated with a group (matching groupId) and a guestbook (matching guestbookId).

public int getGuestbookEntriesCount(long groupId, long guestbookId) {
    return guestbookEntryPersistence.countByG_G(groupId, guestbookId);

Now your local service can get entities matching your criteria and return quick entity counts.

Service Method Prefixes and Transactional Aspects

Service Builder applies transactions to services by adding @Transactional annotations to the *LocalService and *Service interfaces and their methods. By default, Service Builder applies read-only transactions (e.g., @Transactional (readOnly = true ...)) to service methods prefixed with any of these words:

  • dynamicQuery
  • fetch
  • get
  • has
  • is
  • load
  • reindex
  • search

Since these methods operate in read-only transactions, Liferay DXP optimizes their performance. Transactional service methods that don’t have the read-only setting operate in regular transactions.

Important: In methods that operate in read-only transactions, invoking a service method that persists data (adds, updates, or deletes data) must be done via the service object. Using the service object ensures that the defined transactional behavior is applied.


For example, this *LocalServiceImpl’s getter method adds (persists) a ClassName object if no object with that value exists.

public ClassName getClassName(String value) {
    if (Validator.isNull(value)) {
        return _nullClassName;

    ClassName className = _classNames.get(value);

    if (className == null) {
        try {
            className = classNameLocalService.addClassName(value);

Using the service object classNameLocalService to invoke its addClassName method applies the service method’s transaction (the regular transaction specified for the method in the *Service interface). If the addClassName method was invoked WITHOUT using the service object, the ClassName object would not persist because the method’s regular transaction would not be applied.

Creating Local Services

Implementing an Add Method

Defining Service Entity Finder Methods

Understanding the Code Generated by Service Builder

« Implementing Update and Delete MethodsImplementing Any Other Business Logic »
Was this article helpful?
1 out of 1 found this helpful