我应该将实体转换为Repository对象内的DTO并将其返回给服务层? [英] Should I convert an entity to a DTO inside a Repository object and return it to the service layer?

查看:475
本文介绍了我应该将实体转换为Repository对象内的DTO并将其返回给服务层?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


我是否应该将一个实体转换为一个DTO内部的DTO存储库对象并将其返回到服务层?



可以从Repository Layer返回DTO对象吗?


现在我被困在我的Servlet中服务层),例如尝试从 RestaurantOwnerRepository 中检索所有 Restaurant 对象:

 // RestaurantOwnerService(Servlet)

@Override
@Transactional
public List< RestaurantDTO> getAvailableRestaurants(){

List< Restaurant> availableRestaurants = restaurantOwnerRepository.getRestaurants(getSessionId());

返回null;

其中 Restaurant 是一个 @Entity 注释类 - 这似乎是我不应该做的第一件事情,因为服务层现在知道一个非常低级的对象,它违反了尝试抽象我的数据在每一层。



如果我例如将每个 Restaurant 转换为 RestaurantDTO - 但我应该这样做吗?



基本上改变:

  // RestaurantOwnerRepository 

@Override
public List< ;餐厅> getRestaurants(String sessionId){

RestaurantOwner restaurantOwner = this.get(sessionId);

// ..获得餐馆..

return availableRestaurants;

  // RestaurantOwnerRepository 

@Override
public List< Restaurant> getRestaurants(String sessionId){

RestaurantOwner restaurantOwner = this.get(sessionId);

// ..获取餐馆..

返回ConvertEntity.convertRestaurants(availableRestaurants);
}

并且有一个util ConvertEntity

  public class ConvertEntity {

public static List< RestaurantDTO> convertRestaurants(List< Restaurant> restaurants){
// ...
}

}

但这只是我觉得不是最好的解决方案..我可以在这里做什么?




要提到的一个重要的事情是,这将形成一个GWT项目。这意味着我正在使用例如因为它包含在共享项目中,所以在服务器和客户端上 RestaurantDTO

解决方案

现在在您的评论之后更清楚了。让我们再试一次:

首先澄清一下:您的 RestaurantOwnerRepository 实现存储库模式。你的 @Entity 注释对象是hibernate实体,也是DAO代理。您的 RestaurantOwnerService 是一个只能返回与客户端和服务器共享的DTO的GWT服务。



因此,在一个非常简单的服务器端设置中,您有一个DB-Backend,通过hibernate作为持久层访问数据,服务层作为rest-service。在这样的设置中,您的hibernate实体在整个服务器端代码之间共享。例如,您的服务层正在将实体转换为json格式。 Deal?



您的高级设置


  • 持久层


    • 用Hibernate(提供@ Entity-Annotated对象)

    • 也许还有其他的东西


    • 存储库层(您不清楚要返回什么)
    • 服务层(GWT Servlet,与客户端共享)



    存储库层的定义在我看来,这是一个抽象为不同的数据/持久层。它不提供业务逻辑,这更多的是业务层的目的。业务层将上层的输出编译在一起,进行计算并返回结果。但根据您的评论来看,这可能也是您的存储库层中的情况。但可以澄清。



    您的问题:可以从Repository Layer返回DTO对象吗?



    答案:不,从资源库层返回DTO并不是真的。

    为什么: 1.您的DTO是一个转换为可发送到客户端的格式的域实体。它有局限性,因此一些服务器端库不能用于它们。 2.考虑你还想提供其他服务层的情况。 REST接口也许是另一种GUI框架。它们对于转移域实体都有其自身的限制。你真的想复制每个服务层的存储库层吗? 3.考虑想要扩展存储库/业务层的情况,以便它使用 RestaurantOwnerRepository 的输出。你真的想在那里工作吗?



    这就是为什么创建DTO是服务层的目的。所以DTO在客户端和服务层之间共享。同样,您需要在服务层和存储库层共享的对象。我称这些域实体。这些从存储库层返回并由服务层使用。存储库层和持久层之间的情况也是如此。例如,持久层返回存储库层中使用的Hibernate实体。



    在大多数情况下,向下传播多个图层的对象是可行的。所以你可以将你的hibernate实体从存储库层返回到服务层。较新版本的GWT甚至允许使用特殊设置在客户端使用JPA实体。所以你的服务层可以进一步返回你的持久化实体。


    I am trying to get an answer to the two quite similar questions here:

    Should I convert an entity to a DTO inside a Repository object and return it to the Service Layer?

    or

    Is it okay to return DTO objects from the Repository Layer?

    Right now I am stuck in my Servlet (Servie Layer) that e.g. tries to retrieve all Restaurant objects from a RestaurantOwnerRepository:

    // RestaurantOwnerService (Servlet)
    
    @Override
    @Transactional
    public List<RestaurantDTO> getAvailableRestaurants() {
    
        List<Restaurant> availableRestaurants = restaurantOwnerRepository.getRestaurants(getSessionId());
    
        return null;
    }
    

    where Restaurant is a @Entity annotated class - which appears to be the first thing I shouldn't do because the Service Layer does now know about a very low-level object which imho violates the attempt to abstract my data in each layer.

    That wouldn't be the case if I e.g. converted each Restaurant to a RestaurantDTO - but should I do that?

    Basically change:

    // RestaurantOwnerRepository
    
    @Override
    public List<Restaurant> getRestaurants(String sessionId) {
    
        RestaurantOwner restaurantOwner = this.get(sessionId);
    
        // .. getting restaurants ..
    
        return availableRestaurants;
    }
    

    to

    // RestaurantOwnerRepository
    
    @Override
    public List<Restaurant> getRestaurants(String sessionId) {
    
        RestaurantOwner restaurantOwner = this.get(sessionId);
    
        // .. getting restaurants ..
    
        return ConvertEntity.convertRestaurants(availableRestaurants);
    }
    

    and have a util ConvertEntity for every entity like this for example:

    public class ConvertEntity {
    
        public static List<RestaurantDTO> convertRestaurants(List<Restaurant> restaurants) {
            // ...
        }
    
    }
    

    but this just does not feel like the best solution to me.. what could I do here?


    One important thing to mention would be that this comes form a GWT project. That means that I am using e.g. RestaurantDTO on the server and on the client side as it is contained inside a shared project.

    解决方案

    It's more clear now after your comment. Let's try again:

    First, some clarifications: Your RestaurantOwnerRepository implements the repository pattern. Your @Entity annotated objects are hibernate entities and also DAO proxies. Your RestaurantOwnerService is a GWT-Service which can only return a DTO shared with the client and server.

    So in a very simple server-side setup, you have a DB-Backend, access to the data via hibernate as a persistence layer, and a service layer as rest-service. In such a setup your hibernate entities are shared among the whole server side code. Your service layer is converting the entities to json format, for example. Deal?

    Your "advanced" setup

    • Persistence layer
      • with Hibernate (delivering @Entity-Annotated objects)
      • maybe other stuff, too
    • Repository Layer (unclear for you what to return)
    • Service Layer (GWT Servlets, delivering DTOs which are shared with the client side)

    Definition of Repository-Layer: In my opinion, it's an abstraction for different data/persistence layers. It doesn't provide business logic, which is more the purpose of a further business layer. The business layer compiles the outputs of the upper layer together, makes computations and returns the results. But looking according to your comment, this may also be the case in your repository layer. But it's ok for our clarification.

    Your question: Is it okay to return DTO objects from the Repository Layer?

    Answer: No, it is not really okay to return a DTO from the "repository" layer.

    Why: 1. Your DTO is a domain entity transferred into a format which can be sent to the client side. It has limitations so that some server side libraries cannot be used in them. 2. Consider the case that you also want to provide other service layers. A REST-Interface maybe, another GUI-Framework maybe. They all have their own limitations for transferring the domain entities. Do you really want to duplicate the repository layer for each service layer? 3. Consider the case where you want to extend your repository/business layer so that it will use the output of your RestaurantOwnerRepository. Do you really want to work on DTOs there?

    These are why the creation of a DTO is the purpose of a service layer. So the DTO is shared among the client side, and your service layer. In the same sense, you need objects, shared among the service layer and your repository layer. I call these domain entities. These are returned from the repository layer and used by the service layer. Again the same between the repository layer and persistence layer. The persistence layer for example returns the Hibernate entities which are used on the repository layer.

    In most cases, it is ok to propagate your objects from multiple layers downwards. So you can return your hibernate entites from the repository layer to the service layer. Newer versions of GWT even allow to use JPA-entities on the client side with a special setup. So your service layer can further return your persistence entities.

    这篇关于我应该将实体转换为Repository对象内的DTO并将其返回给服务层?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆