DTO vs Value Object vs POCO

By Vladimir Khorikov

In this article, I’d like to clarify the differences in DTO vs Value Object vs POCO where DTO stands for Data Transfer Object, and POCO is Plain Old CLR Object, also known as POJO in Java environment.

DTO vs Value Object vs POCO: definitions

First of all, I want to make a note regarding Value Object. There’s a similar concept in C#, namely Value Type. It’s just an implementation detail of how objects are being stored in memory and I’m not going to touch this. Value Object, which I’m going to discuss is a DDD concept. Check out this article to read more about it.

Alright, let’s start.

You might have noticed that such notions as DTO, Value Object and POCO are often used interchangeably. But are they really synonyms?

DTO is a class representing some data with no logic in it. DTO’s are usually used for transferring data between different applications or different layers within a single application. You can look at them as dump bags of information the sole purpose of which is to just get this information to a recipient.

On the other hand, Value Object is a full member of your domain model. It conforms to the same rules as Entity. The only difference between Value Object and Entity is that Value Object doesn’t have its own identity. It means that two Value Objects with the same property set should be considered the same whereas two Entities differ even if their properties match.

Value Objects do contain logic and, typically, they are not used for transferring data between application boundaries.

POCO (Plain Old CLR Object) is a term created as an analogy for POJO only because “POJO” itself can’t be used in .NET as the letter “J” in it stands for “Java”. Thus, POCO has the same semantics as POJO.

POJO was introduced by Martin Fowler and others to oppose JavaBeans and other heavy-weight enterprise constructions that gained a lot of popularity back in early 2000’s.

The primary goal of POJO is to show that domain can be successfully modeled without bringing to the table complexity related to the execution environment (and JavaBeans brought a lot of it in its early versions). Moreover, the execution environment shouldn’t have anything to do with domain modeling at all.

There’s no direct analogy for JavaBeans in .NET because Microsoft has never introduced the same concept, but we can come up with some made up parallel to help express this concept.

You can think of Component class from System.ComponentModel namespace as an opposite for POCO. There are a lot of classes in .NET that inherit from Component, for example, DBCommand from System.Data and EventLog from System.Diagnostics.

Of course, in most cases, you wouldn’t create a domain class inheriting from Component. It just doesn’t make any sense, because such approach brings a lot of unnecessary complexity, thus contradicting the YAGNI principle.

Another good example of non-POCO approach is Entity Framework before 4.0 version. Every class EF generated inherited from EntityObject base class and thus brought a lot of complexity specific to Entity Framework. Since version 4.0, Entity Framework introduced POCO data model which allows for use of classes that don’t inherit from EntityObject.

That said, POCO stands for use of as simple classes as possible for domain objects. This notion helps conform to YAGNI, KISS and other best practices. POCO classes can contain logic.

DTO vs Value Object vs POCO: correlations

Are there any connections between these terms? There are a few.

First of all, DTO and Value Object represent different concepts and can’t be used interchangeably. On the other hand, POCO is a superset for DTO and Value Object:

DTO vs Value Object vs POCO: relationship

Relationship between DTO, Value Object, and POCO

In other words, Value Object and DTO shouldn’t inherit any heavy-weight enterprise components and thus they are POCO. At the same time, POCO is a wider set: it can be Value Object, Entity, DTO or any other class you might create as long as it doesn’t inherit complexity accidental to your domain.

Here are properties for each of them:

DTO vs Value Object vs POCO: properties

Properties of DTO, Value Object, and POCO

Note that POCO may both have and not have its own identity. It depends on what type of POCO it is: Value Object or Entity. Also, POCO may or may not contain logic in it. It depends on weather or not POCO is DTO.


Alright, I hope I made it at least a little bit clearer. I’d like to summarize this topic with the following:

  • DTO != Value Object
  • DTO ⊂ POCO
  • Value Object ⊂ POCO

  • http://www.thecloudeveloper.com Lincoln Pires

    Hello Vladimir, how are you doing?

    Man, your post is pure and simple as possible and explains things very well!
    Direct to the point and with many forms to remember the concepts you explained.
    Very good post.

    This blog is now on my “follow” folder of favorites / bookmarks.

    Greetings from Brazil.

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Thanks Lincoln, that is very kind from of you to say that!
      Really appreciate you liked that, I tried to distil it as much as I could.

  • Birama

    very nice post. Good job and great information. Thanks from Senegal.

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Thank you!

  • Sabarinathan Arthanari

    Very Good explanation. Nicely sums up. If small note is added, It will be more helpful. As Martin explains if POCO is used for business layer, It must have business logic. Otherwise it will lead to an AnemicDomainModel http://www.martinfowler.com/bliki/AnemicDomainModel.html

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Good point. Thanks!

  • Alexey Pakseykin

    Just a comment for correctness…

    You would want to replace “JavaBeans” with “EJB2” in all 3 paragraphs where `JavaBean` is mentioned. JavaBean is almost as plain as simple POJO – it only requires three properties: default constructor, serializable, getter/setter. At the same time EJB2 neither builds upon nor extends the original JavaBean specification (they are unrelated). And why “2” in “EJB2”? Because only EJB2 were actually heavily bound to the Java EE (rather than being plain business logic components), and recent releases of EJB specification (EJB3+) allow POJOs to be used for the same purpose.

    So, in short, neither “JavaBean” fit the surrounding text nor “EJB” in general – only “EJB2” seems the solution for the “puzzle” to make the paragraphs sound right.

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      I’m no expert in Java or JVM, so feedback from a Java specialist is much appreciated. Changed “JavaBeans” to “EJB2”, thanks!

      • Alexey Pakseykin

        My bad… I didn’t take the effort to construct the text and see how it reads after changes in all cases. And while the main point of changes is not missed, the middle paragraph sounds wrong on specific detail:

        “The primary goal of POJO is to show that domain can be successfully modelled by classes that don’t _inherit_ from EJB2, and, moreover, EJB2 _shouldn’t_ be used for domain modelling at all.”

        Let me put it the right way (feel free to rewrite it your way):

        “The primary goal of POJO is to show that domain can be successfully modelled by classes that are free of code related to execution environment (as legacy EJB2 were compared to recent versions of the specification), and, moreover, the execution environment shouldn’t have anything to do with domain modelling at all.”

        The difference (as you can see) is the fact that nothing tend to “inherit from EJB2” – instead, EJB2 had to implement (undesired) code related to execution environment in addition to the desired code to model domain. In other words, EJB2 (like any EJB since day 1) are actually meant to model the domain.

        In the context of your article with just this one detail (what was POJO and what was not), my comment can be trusted. But I’m also late in Java EE field and haven’t met (legacy) EJB2 – not an expert on history. I have only seen multiple comparisons in articles, books, blogs and so on – e.g. the easiest to quote:
        “EJB 3.0 performs better because it uses POJOs… EJB 2.0 does not implement POJO.”

        Thanks for attention!

        And just a thought while writing this comment… It is obviously impossible to be completely detached from execution environment (ultimately, choice of programming language binds to some details of execution environment). Nevertheless, expressing these aspects declaratively (like in-code annotations or external configuration in EJB3 compared to some container-related implementation like in EJB2) makes model clear.

        • http://enterprisecraftsmanship.com/ Vladimir Khorikov

          Ah, I see, so there aren’t any inheritance, but rather some implicit interface implementation. Updated the article, let me know if you see anything to correct in this version.

          Regarding the complete detachment from the execution environment – indeed! The ToString() and GetHashCode() methods show that no class is actually a POJO/POCO in its purest form. Rather, we have a purity spectrum here.

  • http://www.bravohex.com/ Bravo Hex

    Thanks Vladimir, It’s very helpful for me!

  • Gemma B

    Thanks for your article. I don’t work with Java so the POJO went over my head a little. I picked up what you said about value objects not being used for transferring data through the application.

    Would it be silly to use value objects within dtos. I wanted to use a ProductDTO in my trivial application, setting a price variable as a monetary value. The moment I query my database, I know my price is set in decimal £15.99. However, for another external api, the value is represented in coin value, cents/pence 1599p. Would it be wrong to ensure the type of data my dto is carrying is one my domain model can use.

    Don’t kill me because of my php example:

    public function setPrice(MoneyAsDecimal $price) {
    $this->price = $price;

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      In simple domains, it’s not that important to distinguish between POJOs and DTOs. However, in more complex ones (or if you want to practice your DDD skills), I’d recommend you do explicit conversion between the two. Whenever you use a value inside the domain model, convert it into a Value Object. And whenever this value goes outside of the said model, convert it into a POJO.