英文:
How from Entity to DTO if Entity has an Enum variable?
问题
// Define your DTO interface
public interface DtoEntity {
// Add any common DTO methods here
}
// Your DTO class
@Getter
public class TipoMovimientoDto implements DtoEntity {
private String tipo; // Convert to String as in the Enum's getTipoNombre()
}
// Your service implementation
@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());
tipoMovimientoDto.setTipo(tipoMovimiento.getTipo().getTipoNombre()); // Set the tipo string
tiposMovimientoDto.add(tipoMovimientoDto);
}
return tiposMovimientoDto;
}
// ... (other methods)
}
// Your controller
@RestController
public class PruebasController {
@Autowired
TipoMovimientoService service;
@GetMapping("tiposmovdto")
public ResponseEntity<List<DtoEntity>> findAllDto() {
return ResponseEntity.ok(service.findAllDto());
}
// ... (other methods)
}
This code updates the TipoMovimientoDto
class to have a String tipo
field and sets it during the conversion process. This should help you achieve the desired output in Postman or other REST Client apps when using the DTO version.
英文:
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
得分: 1
我明白了!我从来没有想过这会起作用。
@Getter
public class TipoMovimientoDto implements DtoEntity {
private String tipo;
}
我刚刚在上面的代码(Dto)中做了更改:
private String tipo;
我无法解释实体中的枚举如何被转换为DTO,使用字符串而不是枚举...但这起作用了!
如果你有相同的问题...这是我在枚举和字符串之间的属性转换器:
@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);
}
}
仍然需要在实体类中使用它,放在枚举变量之上:
@Convert(converter = TipoMovEnumConverter.class)
但在DTO中不需要。只需在DTO中使用字符串而不是枚举!
英文:
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!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论