简体   繁体   中英

Do you directly pass hibernate / jpa entity-objects via http or is there an better alternative?

first of all I want to state that I'm fairly new to this JPA / Hibernate thing and also micronaut is new for me (I have much experience in for example PHP, Python, "Desktop Java", C++ and so on).

I cannot get rid of the feel that I'm misunderstanding something in the concept when I'm passing entities via the micronaut @Body annotation as they come in detached and I have to merge them into the persistence context manually using em.merge(entity) .

Please consider the following example (shortened to just show the important portions):

MyEntity.java:

import javax.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Entity
@Table(name = "entities")
@Getter
@Setter
@ToString
public class Entity{
    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected Long id;

    @Column
    protected String name;
}

MyController.java:

import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.*;

@Controller("/entities")
public class EntitiyCrudController {

    @Inject
    private final EntityManager entityManager;

    @Post("/create")
    public HttpResponse create(@Body Entity entity) {
        try {
            entity = entityManager.merge(entity);
            return HttpResponse.ok(entity);
        } catch (ConstraintViolationException exception) {
            return HttpResponse.badRequest();
        }
    }

}

Please note that the samples are just copied together, so there might be some errors, but I think this is more a question that is about the right approach to choose.

During my research all examples I've seen so far are about persisting entities that are not detached. Sometimes I've seen people using DTOs (exact copies of the entity classes on the property level but without the jpa / hibernate annotations). I think this approach also have some smell as I have to build a whole new class which has the exact same properties.

I would have no big problem using DTOs if there weren't the transfering of the properties of the dto to the entity (calling dto getter, calling entity setter). Is there a "clean" way to do this without transfering every property manually (maybe some reflection based library or an annotation processor). Then I could load an entity from the persistence context via the dto id and then update my entity fields and trigger an update.

In summary my problems are: - Passing Entities directly is leading to the entities being detached (So for example the micronaut- data package cannot do updates this way) - Using DTOs one ends up copying property by property which is very verbose

So which is the right way posting an object via json to a webserver and saving or updating it?

If something isn't understandable I'm happy to clarify it!

IMO DTO approach is the way to go ahead when passing data to UI layer from persistence layer. Try using Dozer entity copier ( https://www.baeldung.com/dozer ). This will help you reduce lot of boiler-plate code of copying from one entity to another.

The approach you describe has nothing wrong by itself. But you have to be aware what you are doing, you are coupling your rest interface with your DB implementation. Deppending on your requirements this will probably be a problem. For instance, if your application need Optimistic Concurrency, you will need to add a @Version field in your entity, and you will automatically expose this information through the web service.

Generally you want to have control over the data that is exposed and generally you want to decouple the DB implementation of the rest API. And by the way, generally you also want to have a domain object with business logic for validation, business rules...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM