Can a Plain Old Java Object have methods that deal with business logic other than just the getter/setter methods?
I see possibly mixed answers for this so is there no rigorous definition for this? I know a POJO cannot implement an interface, extend a class, and not use annotation.
You seem to be getting caught up in details of a formal definition that does not exist.
“POJO” is not a precise formal term. “POJO” is a catchy casual term coined by Martin Fowler, Rebecca Parsons, and Josh MacKenzie back in 2000. Specifically, their term was in contrast to the Entity Beans of EJB.
The idea of a POJO is an object that is not enmeshed in a complicated framework. Any experienced Java programmer should be able to read and understand the source code of a POJO without needing to learn some framework, and without needing to look up third-party documentation.
So, a POJO will generally have few annotations only because because Java bundles few annotation classes. Most annotations come from external frameworks. So if we are avoiding the complications of external frameworks, we are avoiding most annotations.
Personally, I would add an exception for one framework: Jakarta Bean Validation (Wikipedia). This framework is relatively simple, does not involve any elaborate involvement, and focuses on the validity/integrity of the POJO’s own internal field values. The validation rules are applied as annotations.
Logging might be another framework exception. And maybe Java Management Extensions (JMX) monitoring too.
Notice that all three of my own personal choices in framework exceptions are focused on the POJOs themselves, as opposed to orchestrating some elaborate involvement with other objects.
And, yes, a POJO can have business logic, especially regarding its own internal state, and regarding its need to communicate its changes with the outside world such as persisting data and notifying other interested parties.
Indeed, you can learn about:
… to see how you can use POJOs as domain objects (“business objects”, with core business logic) while keeping them separate and protected from various elaborate frameworks operating in other parts of your app.
Some classes are intended to simply carry data. All such data-only classes are POJOs. But not all POJOs are data-only classes.
I suggest you learn about Data Transfer Objects and Value Objects, as kinds of data-only classes.
If the main purpose of your class is to communicate data transparently and immutably, use the records feature in Java 16+. In a record, by default, the compiler implicitly creates the constructor, getters, equals
& hashCode
, and toString
.
And let me be clear: there is nothing wrong necessarily with elaborate complicated frameworks. They can be exquisitely useful, obviously. That's why they were invented. Each framework has a purpose and a place.
The term POJO was invented so that in discussions about programming and system architecture/design we can make the distinction between classes that are simple and not entwined versus those classes that are complicated and entwined.