从实体到DTO,如果实体有枚举变量,应该如何处理?

huangapple go评论78阅读模式
英文:

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 = &quot;TIPOS_MOVIMIENTO&quot;)
@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 = &quot;tipoMov&quot;)
private List&lt;Movimiento&gt; 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&#39;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 从实体到DTO,如果实体有枚举变量,应该如何处理?
Well, I think you will understand what I found with this with a image:

从实体到DTO,如果实体有枚举变量,应该如何处理?

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(&quot;Ingreso&quot;),
PRESTAMO(&quot;Prestamo&quot;),
PAGO(&quot;Pago&quot;),
AMORTIZACION(&quot;Amortizaci&#243;n&quot;),
INTERES(&quot;Inter&#233;s&quot;);

private String tipoNombre;


public String getTipoNombre() {
	return tipoNombre;
}


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


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

    case &quot;Pr&#233;stamo&quot;:
    	 return TipoMov.PRESTAMO;

    case &quot;Pago&quot;:
    	 return TipoMov.PAGO;

    case &quot;Amortizaci&#243;n&quot;:
    	 return TipoMov.AMORTIZACION;
    	 
    case &quot;Inter&#233;s&quot;:
   	 return TipoMov.INTERES;

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




}

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&lt;DtoEntity&gt; findAllDto() {

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

	return tiposMovimientoDto;
	
}

public List&lt;TipoMovimiento&gt; findAll() {

	List&lt;TipoMovimiento&gt; tiposMovimiento = repository.findAll();

	return tiposMovimiento;
	
}


}

Service Interface

public interface TipoMovimientoService {


List&lt;DtoEntity&gt; findAllDto();
List&lt;TipoMovimiento&gt; findAll();


}

Controller:

@RestController
public class PruebasController {


@Autowired
TipoMovimientoService service;

@GetMapping(&quot;tiposmovdto&quot;)	
public ResponseEntity &lt;List &lt;DtoEntity&gt; &gt; findAllDto() {
	return ResponseEntity.ok(service.findAllDto());
}

@GetMapping(&quot;tiposmov&quot;)	
public ResponseEntity &lt;List &lt;TipoMovimiento&gt; &gt; 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&lt;TipoMov, String&gt; { 

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!

huangapple
  • 本文由 发表于 2020年8月4日 05:22:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/63237129.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定