Hibernate @瞬态vs装饰器

Hibernate @瞬态vs装饰器,hibernate,jpa,design-patterns,Hibernate,Jpa,Design Patterns,我在建模我的实体时有点矛盾 我们有一个实体,大约有6-8个实例变量。其中两个实际上并没有持久化到数据库中,而是仅用于执行一些验证或显示在UI中。所以,当我们获取实体时,我们会填充一些外部查找 现在,根据我的一位同事的说法,更好的做法是使用decorator,而不是使用@Transient。在某种程度上我同意。因为它澄清了DB所代表的实际模型 但在某些情况下,它会添加额外的样板文件(例如,对于业务,我可以将实体命名为MyEntityBO。但如果我将其用于UI…名称也会有点混乱) 我的问题是,使用@

我在建模我的实体时有点矛盾

我们有一个实体,大约有6-8个实例变量。其中两个实际上并没有持久化到数据库中,而是仅用于执行一些验证或显示在UI中。所以,当我们获取实体时,我们会填充一些外部查找

现在,根据我的一位同事的说法,更好的做法是使用decorator,而不是使用@Transient。在某种程度上我同意。因为它澄清了DB所代表的实际模型

但在某些情况下,它会添加额外的样板文件(例如,对于业务,我可以将实体命名为MyEntityBO。但如果我将其用于UI…名称也会有点混乱)


我的问题是,使用@Transient比使用decorator更好,反之亦然。使用decorator模式的主要缺点是代码维护可能是一个问题(根据我的经验)。
我强烈建议您使用@Transient。

将实体同时用于DB映射和UI映射不是一个好的做法。请始终考虑单一责任原则。实体只负责DB映射,不再负责。您应该为UI表示创建DTO层。但在这种情况下,您还应该创建转换器,我认为太无聊了,我建议使用Mapstruct-。 如果您必须使用@Transient,这是smth出错的第一个迹象,请记住。祝您好运:)


在DTO对象中,您可以创建出于某种目的所需的其他字段或方法

您能详细介绍一下“代码维护”吗?在我们的项目中,Decarator模式有许多类似的对象。因此,在维护过程中,这成为一个令人头痛的问题。此外,如果您计划(将来)迁移,您还会看到哪些问题或不雅的问题这比暂时的模式不方便。但如果你没有小的对象,这也不会是一个问题。我自己也面临着这样的问题。谢谢。出于这个原因,您不应该直接从UI使用实体。您应该有一个视图特定的模型,它是为视图专门设计的模型的表示形式。该视图模型属于UI。视图模型可以通过组合来封装原始模型,但这本身不是装饰器。这就是说,除非你的应用程序是简单的CRUD,在这种情况下,只需使用@Transient即可。你能展示示例代码来说明如何在这里添加装饰器模式吗?@plalx在我的例子中,它并不总是UI。对象也用于其他验证。作文似乎是处理这种情况的更好方法。创建2个对象。ObjectUI,ObjectBO。因此,只有具备UI所需功能的getter才会出现。因此,用户界面不应该看到但应该存在于主实体中的某些内容(例如id/密码)可能会被隐藏。(这里的反论点是“@IgnoreJson”:)我试图理解在什么情况下“@Transient”仍然可行。若像你们所说的那个样,应用程序只是CRUD,那个么在维护这个DTO时只考虑“@Transient”问题就更有意义了。它会创建不必要的详细代码。但如果我让它组合起来,它会让它更易于维护。我的疑问是关于“@Transient”,若实体只是映射数据库结构,那个么为什么他们会创建一个呢?它的动机是什么。在更可行的地方使用这个…但我现在明白了…单一责任原则。我不建议为此使用包装器,你们应该将你们的dao层、服务层和UI层分开。理想情况下,您应该从数据库中获取对象,执行业务逻辑,在UI端构造您需要的对象并发送它。若您发送包装器,则表示该实体位于包装器对象内,这是错误的,因为您将域对象发送到UI。它还可能导致LazyInitException,因为您分离的实体已发送到UI。您应该将完全构造的DTO对象发送到UI。实际上,DTO模式是处理LazyInitException的最佳方式之一。想想你的体系结构,你的层应该耦合得很好,可以处理它们自己的数据。如果您的DTO没有任何方法,这将是完美的,它只是一个哑数据。UI负责处理这些数据
@Entity
public class User {
   @Id
   Long id;
   String name;
}

public class UserDto{
   Long id;
   String name;
}

public class UserConverter{
   public UserDto toDto(User user) {
      if (user == null) return null;
      UserDto dto = new UserDto();
      dto.setId(user.getId());
      dto.setName(user.getName());
      return dto;
   }

   public User toEntity(UserDto dto){...}  
}