【问题标题】:How from Entity to DTO if Entity has an Enum variable?如果实体具有枚举变量,如何从实体到 DTO?
【发布时间】:2020-11-23 23:22:46
【问题描述】:

我正在为我的所有实体创建 DTO 版本。我对具有一个 Enum 值的实体有疑问。这是我的实体:

@Getter
@Setter
@Table(name = "TIPOS_MOVIMIENTO")
@Entity

public class TipoMovimiento {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;

@Column
@Convert(converter = TipoMovEnumConverter.class)
private TipoMov tipo;

public String getTipo() {
    return tipo.getTipoNombre();
}

@OneToMany(mappedBy = "tipoMov")
private List<Movimiento> movimientos;

不,我没有@Enumerated,因为我遵循了一个教程:“JPA 2.1 属性转换器 – 持久化枚举的更好方法”,我不得不删除它。如您所见,我使用转换器。

这是我之前实体的 DTO:

@Getter
public class TipoMovimientoDto implements DtoEntity {


@Convert(converter = TipoMovEnumConverter.class) //I don't even know if write this here!!!!!
private TipoMov tipo;
}

之所以关注that tutorial↑是因为我想在数据库中写入枚举的变量值(tipoNombre)(不是枚举名称本身),因为格式。我想将它存储在带有口音的数据库中,并且我想在 Postman 或任何带有口音的 REST 客户端应用程序中显示它!不要告诉我任何关于在前端格式化它的事情,因为这个项目只是后端:( 好吧,我想你会明白我用这张图片发现了什么:

如果您知道更好的方法,请告诉我,但这不是我现在的问题。

让我告诉你枚举:

public enum TipoMov {

INGRESO("Ingreso"),
PRESTAMO("Prestamo"),
PAGO("Pago"),
AMORTIZACION("Amortización"),
INTERES("Interés");

private String tipoNombre;


public String getTipoNombre() {
    return tipoNombre;
}


TipoMov(String tipoNombre) {
    this.tipoNombre = tipoNombre;
}


public static TipoMov fromDBName(String tipoNombre) {
    switch (tipoNombre) {
    case "Ingreso":
        return TipoMov.INGRESO;

    case "Préstamo":
         return TipoMov.PRESTAMO;

    case "Pago":
         return TipoMov.PAGO;

    case "Amortización":
         return TipoMov.AMORTIZACION;
         
    case "Interés":
     return TipoMov.INTERES;

    default:
        throw new IllegalArgumentException("ShortName [" + tipoNombre
                + "] not supported.");
    }
}




}

问题是如果我将其转换为 DTO 版本,我无法在 Postman 中获得输出。我得到了没有 DTO 的适当输出。我正在使用 REST 服务。让我向您展示服务和控制器。 (它们包括两个版本,没有 DTO 和有 DTO(不起作用)。

服务实现

@Service
public class TipoMovimientoServiceImpl implements TipoMovimientoService {

@Autowired
TipoMovimientoRepository repository;

@Autowired
DtoUtils dtoUtils;


public List<DtoEntity> findAllDto() {

    List<TipoMovimiento> tiposMovimiento = repository.findAll();
    List<DtoEntity> tiposMovimientoDto = new ArrayList();
    
    for (TipoMovimiento tipoMovimiento : tiposMovimiento) {
    
        DtoEntity tipoMovimientoDto= dtoUtils.convertToDto(tipoMovimiento, new TipoMovimientoDto());
        tiposMovimientoDto.add(tipoMovimientoDto);
    }

    return tiposMovimientoDto;
    
}

public List<TipoMovimiento> findAll() {

    List<TipoMovimiento> tiposMovimiento = repository.findAll();

    return tiposMovimiento;
    
}


}

服务接口

public interface TipoMovimientoService {


List<DtoEntity> findAllDto();
List<TipoMovimiento> findAll();


}

控制器:

@RestController
public class PruebasController {


@Autowired
TipoMovimientoService service;

@GetMapping("tiposmovdto")  
public ResponseEntity <List <DtoEntity> > findAllDto() {
    return ResponseEntity.ok(service.findAllDto());
}

@GetMapping("tiposmov") 
public ResponseEntity <List <TipoMovimiento> > findAll() {
    return ResponseEntity.ok(service.findAll());
}

}

正如我所说,nonDto 版本完美运行,但 DTO 版本没有。不是 DTO 转换器的错,因为我有其他 REST 服务(没有枚举)与 DTO 完美配合。这是使Enum和Dto兼容的问题!

【问题讨论】:

  • 我认为这是一个糟糕的设计问题。您不会将 DTO 保存到数据库中。在控制器中接收到它们后,您立即使用相应的服务转换它们,然后您保留实际实体 - 而不是 DTO。老实说,我认为你应该重写它,而不是进一步继承糟糕的设计。

标签: java spring rest enums spring-data


【解决方案1】:

我明白了!!!我从没想过这会奏效。

@Getter
public class TipoMovimientoDto implements DtoEntity {

private TipoMov tipo;

}

我只是在上面的代码中改了(Dto):

私有 TipoMov 提示;

私有 字符串 提示;

我无法解释如何将 Entity 中的 Enum 转换为 DTO,使用 String 而不是 Enum...但这有效!

如果你有同样的问题......这是我的枚举和字符串之间的属性转换器

@Converter(autoApply = true)
public class TipoMovEnumConverter implements AttributeConverter<TipoMov, String> { 

public String convertToDatabaseColumn(TipoMov tipoMov) {
    return tipoMov.getTipoNombre();
}

    public TipoMov convertToEntityAttribute(String dbData) {
        return  dbData == null ? null : TipoMov.fromDBName(dbData);
    }
    
}

仍然需要在Entity类中使用它,在枚举变量之上:

@Convert(converter = TipoMovEnumConverter.class)

但在 DTO 中不是必需的。只需在 DTO 中使用 String 而不是 Enum!

【讨论】:

    猜你喜欢
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-21
    • 2019-08-08
    • 2012-04-03
    相关资源
    最近更新 更多