Ask Questions and Find Answers
Important:
Ask is now read-only. You can review any existing questions and answers, but not add anything new.
But - don't panic! While ask is no more, we've replaced it with discuss - the new Liferay Discussion Forum! Read more here here or just visit the site here:
discuss.liferay.com
RE: Best practice on Primary Keys for Service Builder Entities
We have been working through a project taking full advantage of the service builder and then using these entities across the additional frameworks/features such as search Document Contributors and also adding them to Segment Criteria Contributors.
Through this process, it has become apparent one really _must_ use a long data type for primary keys in order to make this all work together without a lot of extra lifting. It feels that the documentation could have been more proactive in helping expose this design requirement clearly.
Granted, in _every_ example of the Service Builder it seems the long data type for the primary key, but I don't know that it was every stated _why_ that choice is important and it felt a little passive given how it seems to be a very important design/architecture decision if you plan to tied the entities in with the rest of the frameworks.
For example
1) the classPK field is a long and if you want to take advantage of the default Document Contributor for search, you'll need to have your primaryKey be a long;
2) the lack of ActionableDynamicQuery methods if you are not using a long primary key. but those methods seem to be a requirement for the Segments Criteria Contributor to work.... I assume there are others? If so, where can/should we contribute to the documentation on this type of conversation?
Any others come across this? If not, its here for those who may search in the future.
Through this process, it has become apparent one really _must_ use a long data type for primary keys in order to make this all work together without a lot of extra lifting. It feels that the documentation could have been more proactive in helping expose this design requirement clearly.
Granted, in _every_ example of the Service Builder it seems the long data type for the primary key, but I don't know that it was every stated _why_ that choice is important and it felt a little passive given how it seems to be a very important design/architecture decision if you plan to tied the entities in with the rest of the frameworks.
For example
1) the classPK field is a long and if you want to take advantage of the default Document Contributor for search, you'll need to have your primaryKey be a long;
2) the lack of ActionableDynamicQuery methods if you are not using a long primary key. but those methods seem to be a requirement for the Segments Criteria Contributor to work.... I assume there are others? If so, where can/should we contribute to the documentation on this type of conversation?
Any others come across this? If not, its here for those who may search in the future.
So this usually comes from the fact that Liferay is database-agnostic...
Some databases are better at handling complex and varchar keys, some aren't. Since Liferay wants to run on all, using a long key is a lot easier.
Also architecturally most databases will prefer long PKs over any other type. Oracle has sequences (longs) for example, and other databases support other mechanisms such as auto-increment fields for ids.
Additionally, it is actually better to use surrogate rather than natural keys for any table in any database. Natural keys are typically flexible and subject to change (regardless how infrequently). Surrogate keys, on the other hand, since they have no real business meaning, they can be rigid and static.
Historically, it has also been perceived that a long PK will index faster, will search faster, and will basically have better performance. I don't know if this is true or if it just an old geek's tale.
Some databases are better at handling complex and varchar keys, some aren't. Since Liferay wants to run on all, using a long key is a lot easier.
Also architecturally most databases will prefer long PKs over any other type. Oracle has sequences (longs) for example, and other databases support other mechanisms such as auto-increment fields for ids.
Additionally, it is actually better to use surrogate rather than natural keys for any table in any database. Natural keys are typically flexible and subject to change (regardless how infrequently). Surrogate keys, on the other hand, since they have no real business meaning, they can be rigid and static.
Historically, it has also been perceived that a long PK will index faster, will search faster, and will basically have better performance. I don't know if this is true or if it just an old geek's tale.
Good detail and that totally makes sense as a best practice and for architectural reasons that are part of what makes the awesomeness of Liferay.
However, for developers working with pre-existing data definitions or situations whereby they may not be starting from scratch, I think it's helpful to note that not only is it a best practice kind of thing, but if you plan to integrate your entities with the other Liferay frameworks, it actually a _MUST_ do. Would that be an appropriate statement?
Does it jive what I'm getting at? Just thinking about it from the viewpoint of the folks who are making the implementation decisions (especially for integrations/migrations... and deciding what data model needs to conform and why.
However, for developers working with pre-existing data definitions or situations whereby they may not be starting from scratch, I think it's helpful to note that not only is it a best practice kind of thing, but if you plan to integrate your entities with the other Liferay frameworks, it actually a _MUST_ do. Would that be an appropriate statement?
Does it jive what I'm getting at? Just thinking about it from the viewpoint of the folks who are making the implementation decisions (especially for integrations/migrations... and deciding what data model needs to conform and why.
Existing tables/data can be kind of sticky, and I'm guessing each case may need to be handled differently?
If I had to, for example, make an asset out of an existing record, probably my first approach would be to create a Liferay SB entity for the record, even if it is just going to hold the primary key that's the foreign key to the other table.
Why? Well having a long primary key is just the first thing. When you create an asset entry from scratch you end up with the audit columns, group and company id columns, ... I wouldn't want to modify an existing record to include these columns since they are likely going to be managed and used only from Liferay.
So creating a new entry, one that can hold these bits of data and have all of the necessary Liferay pieces to be treated as a full-blown asset, well that just seems like the right thing to do.
Is that the right answer every time? Maybe not. Most of the time external datasources are wired in to consume or update business data, and since those aren't typically going to be individual assets, the kind of restrictions for PK type might not be necessary at all.
If I had to, for example, make an asset out of an existing record, probably my first approach would be to create a Liferay SB entity for the record, even if it is just going to hold the primary key that's the foreign key to the other table.
Why? Well having a long primary key is just the first thing. When you create an asset entry from scratch you end up with the audit columns, group and company id columns, ... I wouldn't want to modify an existing record to include these columns since they are likely going to be managed and used only from Liferay.
So creating a new entry, one that can hold these bits of data and have all of the necessary Liferay pieces to be treated as a full-blown asset, well that just seems like the right thing to do.
Is that the right answer every time? Maybe not. Most of the time external datasources are wired in to consume or update business data, and since those aren't typically going to be individual assets, the kind of restrictions for PK type might not be necessary at all.
Copyright © 2025 Liferay, Inc
• Privacy Policy
Powered by Liferay™