问题
I'm creating DTO versions of all my entities. I have a problem with an entity that has one Enum value. This is my entity:
@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;
No, I don't have @Enumerated because I followed a tutorial: "JPA 2.1 Attribute Converter – The better way to persist enums" and I had to remove it. I use a converter, as you can see.
This is my DTO of the previous entity:
@Getter
public class TipoMovimientoDto implements DtoEntity {
@Convert(converter = TipoMovEnumConverter.class) //I don't even know if write this here!!!!!
private TipoMov tipo;
}
The reason why I've followed that tutorial ↑ is because I wanted to write in database the variable values (tipoNombre) of enum (not enum name itself) because format. I want to store it in DB with accents, and I want to show it in Postman or whatever REST Client app with accents! Don't tell me anything about format it in front-end because this project is only back-end :( Well, I think you will understand what I found with this with a image:
If you know a better way to do this, let me know, but this is not my problem now.
Let me show you the Enum:
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.");
}
}
}
The problem is that I can't get the output in Postman if I convert this to DTO version. I get the appropiate output without DTO. I'm using REST services. Let me show you the services and controller. (They include both versions, without DTO and with DTO (that is not working)).
ServiceImpl
@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;
}
}
Service Interface
public interface TipoMovimientoService {
List<DtoEntity> findAllDto();
List<TipoMovimiento> findAll();
}
Controller:
@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());
}
}
As I said, the nonDto version works perfectly, but DTO version no. Is not the fault of DTO converter, because I have other REST services (that don't have enums) working perfectly with DTO. This is a problem about making compatible Enum and Dto!
回答1:
I got it!!! I never thought this would work.
@Getter
public class TipoMovimientoDto implements DtoEntity {
private TipoMov tipo;
}
I just changed in the code above (Dto):
private TipoMov tipo;
to
private String tipo;
I can't explain how Enum from Entity could have been converted to DTO, using String instead Enum... But that worked!
In case you have the same problem... this is my Attribute Converter between Enum and String
@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);
}
}
Is still necessary to use it in Entity class, above of the enum variable:
@Convert(converter = TipoMovEnumConverter.class)
But not necessary in DTO. Just use String instead Enum in DTO!
来源:https://stackoverflow.com/questions/63237129/how-from-entity-to-dto-if-entity-has-an-enum-variable