Home > database >  No converter found capable of converting from type X to type Y
No converter found capable of converting from type X to type Y

Time:06-05

I'm facing this error

 No converter found capable of converting from type [java.lang.Integer] to type [@org.springframework.data.jpa.repository.Query com.kevcode.saludxi.citasmcs.models.entity.Appointment] 

When I try to use @Query in my method.

Method:

@Query("SELECT a.id, a.appointmentDate, a.appointmentTypeId, at.name as appointmentTypeName, "  
            "a.feeValue, at.lengthInMinutes, a.medicId, a.patientId, a.symptomId"  
            " FROM Appointment a INNER JOIN AppointmentType at ON at.id = a.appointmentTypeId"  
            " WHERE a.appointmentDate >= ?1 AND a.appointmentDate <=  ?2 AND a.medicId = ?3")
    List<Appointment> findAllBetweenDateAndMedicId(Date maxDate, Date minDate, int medicId);

Appointment Class

public class Appointment extends EntityBase {
    //private int id **extended from EntityBase**
    private int appointmentTypeId;
    private int symptomId;
    private int medicId;
    private int patientId;
    @Column(name="appointmet_date")
    private LocalDateTime appointmentDate;
    private float feeValue;
    @Transient
    private int lengthInMinutes;
    @Transient
    private String appointmentTypeName;
}

Stacktrace:

org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.Object[]] to type [@org.springframework.data.jpa.repository.Query com.kevcode.saludxi.citasmcs.models.entity.Appointment] for value '{78532, 2022-05-24 00:46:14.0, 2, Examen, 3000.0, 30, 61, 21, 41}'; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.Integer] to type [@org.springframework.data.jpa.repository.Query com.kevcode.saludxi.citasmcs.models.entity.Appointment]

CodePudding user response:

A quick solution, since you can't return Appointment base entities directly as you are requesting what seems to be unmapped values, is to use a constructor query to have JPA return POJOs instead of managed entities:

@Query("SELECT new package.Appointment(a.id, a.appointmentDate, a.appointmentTypeId, at.name, "  
            "a.feeValue, at.lengthInMinutes, a.medicId, a.patientId, a.symptomId)"  
            " FROM Appointment a INNER JOIN AppointmentType at ON at.id = a.appointmentTypeId"  
            " WHERE a.appointmentDate >= ?1 AND a.appointmentDate <=  ?2 AND a.medicId = ?3")

You then need a constructor in the Appointment class that takes in all these values in the same order (and type) used in the query:

public class Appointment extends EntityBase {
    //private int id **extended from EntityBase**
    private int appointmentTypeId;
    private int symptomId;
    private int medicId;
    private int patientId;
    @Column(name="appointmet_date")
    private LocalDateTime appointmentDate;
    private float feeValue;
    @Transient
    private int lengthInMinutes;
    @Transient
    private String appointmentTypeName;
    public Appointment(int id, LocalDateTime appointmentDate, int appointmentTypeId, String appointmentTypeName, float feeValue, int lengthInMinutes, int medicId, int patientId, int symptomId){
      this.setId(id);
      this.appointmentDate = appointmentDate;
      ..
    }
}

Remember though that Appointment instances fetched in this manner are not managed by JPA, so changes to them are not tracked and synchronized to the database. You might be better off using a separate view object that reflects that this 'appointment' data is really appointment and AppointmentType data, though I'm not sure why you shouldn't just have Appointment have a ManyToOne reference to AppointmentType:

public class Appointment extends EntityBase {
  ..
  @ManyToOne
  @JoinColumn(name="appointmentTypeId")
  private AppointmentType appointmentType;
}

Allowing it to be sent across with Appointments, so the type name, lengthInMinutes and any other properties are always accessible - or lazily fetched on demand.

  • Related