简体   繁体   English

我应该将实体转换为Repository对象内的DTO并将其返回到服务层吗?

[英]Should I convert an entity to a DTO inside a Repository object and return it to the service layer?

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? 我应该将实体转换为Repository对象内的DTO并将其返回到服务层吗?

or 要么

Is it okay to return DTO objects from the Repository Layer? 可以从存储库层返回DTO对象吗?

Right now I am stuck in my Servlet (Servie Layer) that eg tries to retrieve all Restaurant objects from a RestaurantOwnerRepository : 现在我陷入了我的Servlet(Servie层),例如尝试从RestaurantOwnerRepository检索所有的Restaurant对象:

// 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. 其中Restaurant是一个@Entity注释类 - 这似乎是我不应该做的第一件事,因为Service Layer现在知道一个非常低级的对象,它违反了在每一层中抽象数据的尝试。

That wouldn't be the case if I eg converted each Restaurant to a RestaurantDTO - but should I do that? 如果我将每家Restaurant改为RestaurantDTO那就不是这样了 - 但我应该这样做吗?

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: 并为每个像这样的实体使用util ConvertEntity ,例如:

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. 值得一提的是,这是一个GWT项目。 That means that I am using eg RestaurantDTO on the server and on the client side as it is contained inside a shared project. 这意味着我在服务器和客户端使用例如RestaurantDTO ,因为它包含在共享项目中。

It's more clear now after your comment. 你的评论后现在更清楚了。 Let's try again: 让我们再试一次:

First, some clarifications: Your RestaurantOwnerRepository implements the repository pattern. 首先,澄清一下:您的RestaurantOwnerRepository实现了存储库模式。 Your @Entity annotated objects are hibernate entities and also DAO proxies. 您的@Entity注释的对象是休眠实体以及DAO代理。 Your RestaurantOwnerService is a GWT-Service which can only return a DTO shared with the client and server. 您的RestaurantOwnerService是一个GWT服务,它只能返回与客户端和服务器共享的DTO。

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. 因此,在一个非常简单的服务器端设置中 ,您有一个DB-Backend,通过hibernate作为持久层访问数据,以及作为rest-service的服务层。 In such a setup your hibernate entities are shared among the whole server side code. 在这样的设置中,您的hibernate实体在整个服务器端代码之间共享。 Your service layer is converting the entities to json format, for example. 例如,您的服务层将实体转换为json格式。 Deal? 交易吗?

Your "advanced" setup 您的“高级”设置

  • Persistence layer 持久层
    • with Hibernate (delivering @Entity-Annotated objects) 使用Hibernate(提供@ Entity-Annotated对象)
    • 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) 服务层(GWT Servlet,提供与客户端共享的DTO)

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? 您的问题:从存储库层返回DTO对象是否可以?

Answer: No, it is not really okay to return a DTO from the "repository" layer. 答:不,从“存储库”层返回DTO并不是真的可以。

Why: 1. Your DTO is a domain entity transferred into a format which can be sent to the client side. 原因: 1。您的DTO是一个域实体,转换为可以发送到客户端的格式。 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. 2.考虑您还想提供其他服务层的情况。 A REST-Interface maybe, another GUI-Framework maybe. 一个REST接口可能,另一个GUI框架可能。 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 . 3.考虑您希望扩展存储库/业务层以便它将使用RestaurantOwnerRepository的输出的情况。 Do you really want to work on DTOs there? 你真的想在那里做DTO吗?

These are why the creation of a DTO is the purpose of a service layer. 这就是为什么创建DTO是服务层的目的。 So the DTO is shared among the client side, and your service layer. 因此,DTO在客户端和服务层之间共享。 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. 例如,持久层返回在存储库层上使用的Hibernate实体。

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. 因此,您可以将hibernate entites从存储库层返回到服务层。 Newer versions of GWT even allow to use JPA-entities on the client side with a special setup. 较新版本的GWT甚至允许在客户端使用JPA实体进行特殊设置。 So your service layer can further return your persistence entities. 因此,您的服务层可以进一步返回您的持久性实体。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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