Why Do We Need Entity Objects

why we need to identify the entity and value object?

Before the advent of DDD, we model the domain without entity and value object.After the DDD was put forwar,we use entity and value object to classify domain object, so what is the advantage of such classification?

You should review Chapter 5 ("A Model Expressed in Software") of the Blue Book.

Evans writes:

Defining objects that clearly follow one pattern or the other makes the objects less ambiguous and lays out the path toward specific choices for robust design.

Tracking the identity of ENTITIES is essential, but attaching identity to other objects can hurt system performance, add analytical work, and muddle the model by making all objects look the same.

... bidirectional associations between two VALUE OBJECTS just make no sense. Without identity, it is meaningless to say that an object points back to the same VALUE OBJECT that points to it. The most you could say is that it points to an object that is equal to the one pointing to it, but you would have to enforce that invariant somewhere.

My own summary would be this: recognizing that some domain concepts are entities is useful, because it encourages the designer to acknowledge that identity, continuity, and life cycle are important concerns for the entity in this domain. Similarly, recognizing that a concept is a value immediately frees you from those concerns, bringing your attention to their immutable nature and equivalence.

Is there a difference between an Entity and a object?

Generally speaking, an entity is an abstract concept that's typically represented by a table in a database schema. The term object usually refers to in-memory data structures. An object that represents an entity may be called an entity object (often mapped to a row in a database table), that is it's an instance of an entity class (often mapped to a table).

In the .NET Framework (3.5 SP1) an entity is part of an instance of the EDM (Entity Data Model), and is mapped to rows in one or more tables. For example, ther can be a Customer entity type that can map to a single Customer database table or it may also extend to a CustomerPreferences table as well. Using the EntityProvider, you can access entites, as if they were just rows in database tables, using eSQL. The EDM model is also known as the conceptual layer.

There is another layer on top of the EDM model known as the object layer, where entities are materialized as EDM-mapped objects.

When do we need to .save() an entity in Spring?

Conclusion

It depends on whether the method is contained in a transaction or not.

  • In a transaction: the above code works as expected implicitly.
  • Not in a transaction: the .save() must be called explicitly to update the database.

How can I detect cases like these and know exactly when to use the .save() method and when can I ignore it?

  • The .save() method must be called for a modified entity explicitly if:

    1. The changing code does not belong to a transaction.
    2. The entity is newly created: new Car().
    3. The entity object is obtained externally, not from the database within the same transaction. (E.g. already saved in a List before the transaction begins.)
  • The .save() method does not have to be called for entities which are queried from JPA within the same transaction. (E.g. carRepository.findById(id) and other similar methods).

Transaction

If the above sequence of events is called from a method annotated by @Transactional, then it would work as expected.

Then the created Car object becomes managed by the persistence context and all changes to it, within the same transaction, are flushed after the transaction is completed.

No Transaction

If the above method does not belong to any transaction, all changes to the objects are local (object properties change, but are not flushed to database).

That is why calling persist() or merge() (in the above case, save() which internally uses those two) must be done explicitly to flush the changes.

Better to Use Transactions

Saving a single entity executes a single SQL query, which is atomic, thus a transaction itself. If the sequence of database events is not contained in a transaction, then each save() call acts as a standalone "transaction".

Usually, this is bad practice, because if one of the later "transactions" fail (some kind of Exception thrown), the previous succeeded transactions have already been flushed, possibly bringing the database to an invalid state from the business logic perspective.


Open Session In View

The behavior has nothing to do with OSIV.

OSIV keeps the database session open during view rendering, so that further queries (transactions) could be performed after the main request processing has finished, in the view layer. Using OSIV is widely considered an anti-pattern.

  • Why is Hibernate Open Session In View considered a bad practice?
  • JPA @Entity not managed after creation?

What's the point of having DTO object when you have the same object as POJO (Entity)?

This answer is a replica of what can be found on stack exchange. IMHO the OP should be closed for being posted in the wrong forum. It's currently also attracting opinionated answers, though not necessarily so, and isn't tied to java in any particular way.

DTO is a pattern and it is implementation (POJO/POCO) independent. DTO says, since each call to any remote interface is expensive, response to each call should bring as much data as possible. So, if multiple requests are required to bring data for a particular task, data to be brought can be combined in a DTO so that only one request can bring all the required data. Catalog of Patterns of Enterprise Application Architecture has more details.

DTO's are a fundamental concept, not outdated.

What is somewhat outdated is the notion of having DTOs that contain no logic at all, are used only for transmitting data and "mapped" from domain objects before transmission to the client, and there mapped to view models before passing them to the display layer. In simple applications, the domain objects can often be directly reused as DTOs and passed through directly to the display layer, so that there is only one unified data model. For more complex applications you don't want to expose the entire domain model to the client, so a mapping from domain models to DTOs is necessary. Having a separate view model that duplicates the data from the DTOs almost never makes sense.

However, the reason why this notion is outdated rather than just plain wrong is that some (mainly older) frameworks/technologies require it, as their domain and view models are not POJOS and instead tied directly to the framework.

Most notably, Entity Beans in J2EE prior to the EJB 3 standard were not POJOs and instead were proxy objects constructed by the app server - it was simply not possible to send them to the client, so you had no choice about haing a separate DTO layer - it was mandatory.

Although DTO is not an outdated pattern, it is often applied needlessly, which might make it appear outdated.

From Java guru Adam Bien:

The most misused pattern in the Java Enterprise community is the DTO. DTO was clearly defined as a solution for a distribution problem. DTO was meant to be a coarse-grained data container which efficiently transports data between processes (tiers). ~ Adam Bien

From Martin Fowler:

DTOs are called Data Transfer Objects because their whole purpose is to shift data in expensive remote calls. They are part of implementing a coarse grained interface which a remote interface needs for performance. Not just do you not need them in a local context, they are actually harmful both because a coarse-grained API is more difficult to use and because you have to do all the work moving data from your domain or data source layer into the DTOs. ~ Martin Fowler

Here is a Java EE specific example of a common but incorrect use of the DTO pattern. If you're unfamiliar with Java EE, you just need to know the MVC pattern: a "JSF ManagedBean" is a class used by the View, and a "JPA Entity" is the Model in the MVC pattern.

So, for example, say you have a JSF ManagedBean. A common question is whether the bean should hold a reference to a JPA Entity directly, or should it maintain a reference to some intermediary object which is later converted to an Entity. I have heard this intermediary object referred to as a DTO, but if your ManagedBeans and Entities are operating within the same JVM, then there is little benefit to using the DTO pattern.

Futhermore, consider Bean Validation annotations (again, if you're unfamiliar with Java EE, know that Bean Validation is an API for validating data). Your JPA Entities are likely annotated with @NotNull and @Size validations. If you're using a DTO, you'll want to repeat these validations in your DTO so that clients using your remote interface don't need to send a message to find out they've failed basic validation. Imagine all that extra work of copying Bean Validation annotations between your DTO and Entity, but if your View and Entities are operating within the same JVM, there is no need to take on this extra work: just use the Entities.

The Catalog of Patterns of Enterprise Application Architecture provides a concise explanation of DTOs, and here are more references I found illuminating:

  • HOW TO DEAL WITH J2EE AND DESIGN PATTERNS
  • How to use DTO in JSF + Spring + Hibernate
  • Pros and Cons of Data Transfer Objects Martin Fowler's description of DTO
  • Martin Fowler explains the
    problem with DTOs. Apparently they were being misused as early
    as 2004

Why need detached entities in JPA?

I will explain why that scenario should not occur and why we need detached entities.

Consider you are in a JTA transaction (JPA requires support for it) and fetch a.
Now you can call a.getB() either (1) in this transaction (i.e entity a is managed) or (2) when a is detached.

Scenario 1: now depending on your transaction isolation level, you might see or might not see what other transactions do. For example, if you have the SERIALIZABLE isolation level, then you will successfully fetch a.getB(), even if that row was deleted in a concurrent transaction. If that row was already deleted and your transaction sees that, it means that either your DB is inconsistent (no foreign key) or that you used the wrong transaction isolation level.

Scenario 2: the entity a is detached. When a LazyInitializationException is thrown, that means to me that you called a.getB() too late in order to guarantee a consistence in your application (as a is not managed anymore). In order to solve the problem you simply call it earlier when the entity is still managed. A NPE cannot occur.

Why we need the DETACHED STATE? Well, we need a state in which the changes to an entity instance are not tracked. Why?

Example 1: suppose you receive an entity (with persistent identity) in the EJB layer and that there were no detached state (meaning all entities should be managed). But we need to do a validation before persisting the entity. If that entity would be automatically managed, its changes would be automatically persisted to DB. So this new state was introduced.

Example 2: you receive in the EJB layer an entity, any you need to update ONLY 5 fields of 10 from that entity. If that entity would get automatically into the managed state, all 10 fields would be persisted. The solution in this case is to fetch a managed entity and to update the 5 fields ONLY in that entity.

Should entity class be used as request body

You should create a DTO class and map it to persistence class. Refer this rule description for the same. Reason specified is

if a persistent object is used as an argument of a method annotated with @RequestMapping, it’s possible from a specially crafted user input, to change the content of unexpected fields into the database

Apart from this, using DTO we can omit some of the persistent object properties that we don't wish to be present/visible in presentation layer.

You can map DTO class to persistence entity in controller itself like below.

@RestController
@RequestMapping("books")
public class BookController {

@Autowired
BookRepository bookRepository;

@Autowired
ModelMapper modelMapper

@PostMapping
public Book saveBook(@RequestBody BookDTO modelBook) {
Book book = this.modelMapper.map(modelBook, Book.class);
return bookRepository.save(book);
}
}

ModelMapper is a framework that does the DTO to Entity and vice versa mapping. Check ModelMapper website.

You may refer answer and comments for more information about the same.



Related Topics



Leave a reply



Submit