← Alle Beiträge
Liferay DXPLiferay ObjectsOSGiHeadless APIsJava

Skip the Headless API: Calling Liferay Objects Directly with ObjectEntryManager

Von LR Tools · August 23, 2026 · 4 min read

This is LR Tools’ rewrite of a post by Laxit Khanpara on Liferay.dev covering a service-layer shortcut that’s easy to miss if you’ve only ever touched Liferay Objects through their REST API.

Two ways to talk to a Liferay Object

Liferay Objects let you model and manage custom data without a traditional Service Builder module, and most developers reach for the Headless REST API to work with them — an endpoint pattern like /o/c/{objectName} that’s well documented and works well for frontend applications and external integrations. What’s less obvious is that those Headless APIs are themselves built on top of an internal service layer, and backend code running inside an OSGi module can call that same layer directly — ObjectEntryManager — skipping the HTTP round-trip entirely.

What ObjectEntryManager actually is

ObjectEntryManager is the internal service that handles Object operations: creating entries, retrieving data, updating entries, deleting records, and searching or filtering. Four pieces are involved:

import com.liferay.object.model.ObjectDefinition;
import com.liferay.object.rest.dto.v1_0.ObjectEntry;
import com.liferay.object.rest.manager.v1_0.ObjectEntryManager;
import com.liferay.object.rest.manager.v1_0.ObjectEntryManagerRegistry;

ObjectDefinition represents the Object’s schema, ObjectEntry represents its data, ObjectEntryManager provides the CRUD operations, and ObjectEntryManagerRegistry resolves the correct manager implementation for a given Object.

Using it, step by step

Inject the registry:

@Reference
private ObjectEntryManagerRegistry objectEntryManagerRegistry;

Look up the Object you’re working with:

ObjectDefinition objectDefinition = ObjectDefinitionLocalServiceUtil.getObjectDefinitionByExternalReferenceCode("YOUR_OBJECT_ERC", companyId);

Get the manager for that Object’s storage type:

ObjectEntryManager objectEntryManager = objectEntryManagerRegistry.getObjectEntryManager(objectDefinition.getStorageType());

Create an entry:

Map<String, Serializable> values = new HashMap<>();
values.put("name", "John Doe");
values.put("email", "john@example.com");
long userId = contextUser.getUserId(); // or themeDisplay.getUserId()
ObjectEntry objectEntry = objectEntryManager.addObjectEntry(
    userId, objectDefinition, values, null, null
);

Retrieve a single entry, or a page of entries:

ObjectEntry entry = objectEntryManager.getObjectEntry(
    objectDefinition, entryId
);

Page<ObjectEntry> page = objectEntryManager.getObjectEntries(
    objectDefinition, null, null, null, Pagination.of(1, 10)
);

Pagination works the way you’d expect:

Pagination pagination = Pagination.of(1, 20);

Page<ObjectEntry> page = objectEntryManager.getObjectEntries(
    objectDefinition, null, null, null, pagination
);

Additional filtering and sorting can be layered on from there depending on what the use case needs.

Why this is actually faster

Going through the Headless API means: application → HTTP request → Headless API → service layer → database. Calling ObjectEntryManager directly collapses that to: application → ObjectEntryManager → database. Removing the HTTP hop is the entire performance argument — it’s not a different set of capabilities, just a shorter path to the same service layer the REST API already calls internally.

Permissions still apply

ObjectEntryManager doesn’t bypass permission checks — it enforces them against whatever user context you pass in:

long userId = contextUser.getUserId();

Always pass the actual current user’s context, confirm their roles genuinely have the Object permissions the operation needs, and avoid reaching for an admin user unless there’s a real reason to. Permissions are evaluated the same way regardless of which path — REST or direct service call — you took to get there.

When to reach for it, and when not to

ObjectEntryManager is the right call inside an OSGi module implementing backend business logic, when performance matters, or when you want to avoid an unnecessary internal HTTP call. It’s the wrong call for public or external APIs, frontend code that expects REST endpoints, anything requiring OAuth-based access, or situations where a loosely-coupled architecture is actually what you want.

Use case Approach
Frontend or external systems Headless APIs
Backend processing and internal logic ObjectEntryManager

The takeaway

Headless APIs remain the right tool for external and frontend integration — nothing here argues against them. For backend-only processing running inside an OSGi module, though, going straight to the service layer through ObjectEntryManager is a faster, simpler path to the same data, without giving up permission enforcement along the way.

This article is LR Tools’ rewrite of the original post by Laxit Khanpara — read it on Liferay.dev for the author’s own framing.

Dieser Artikel ist adaptiert von: Laxit Khanpara, Liferay.dev

Mehr aus dem Blog

Liferay DXPPostgreSQLDatabase Migration

Migrating Liferay to PostgreSQL: A More Reliable Alternative to Liferay's Beta Tool

August 23, 2026 · 3 min read

Liferay's own database migration tool is still Beta and unreliable in practice. Here's a third-party alternative, the exact 8-step migration procedure, and links to the tool and its docs.

Liferay DXPSecurityCVE

When a CVE Isn't a Liferay Vulnerability: Presence vs. Reachability

August 23, 2026 · 7 min read

A security scanner finding a CVE in a bundled library isn't proof that Liferay DXP is exploitable through it. Here's how Liferay's security team tells the difference — and why an unnecessary dependency upgrade isn't automatically the safer choice.

Liferay DXPFree TierLicensing

DXP Free Tier Licenses: Why the Product Version Doesn't Have to Match Your Runtime

August 23, 2026 · 3 min read

A DXP Free Tier activation key stamped with a quarterly release that hadn't shipped yet looked like a bug. It wasn't — here's what the product-version field in a Liferay license actually means, and why it isn't a strict compatibility gate.