I have a FacturaService class that has another MailService class injected.
Through the "sendInvoice" method I receive a pdf invoice and send it by email.
The problem comes when I receive many calls in a row, because apparently the calls are made faster than it takes to attach the pdfs to the email (This is just a theory that I have), and the result is that the same invoice is sent to some clients. And then another invoice to as many other clients, and so on. (I want to point out that the process of sending invoices by mail works well when the calls are made one by one)
I have tried annotating both the InvoiceService class and the EmailService class with @Scope("prototype"), but to no avail.
CLASS INVOICESERVICE
@Service
public class FacturaService {
@Autowired
private FacturaRepository facturaRepository;
@Autowired
private FacturaValidation facturaValidation;
@Autowired
private ClienteService clienteService;
@Autowired
private LecturaRepository lecturaRepository;
@Autowired
private LineaDetalleService lineaDetalleService;
@Autowired
private LineaDetalleRepository lineaDetalleRepository;
@Autowired
private EmpresaService empresaService;
@Autowired
private RemesaService remesaService;
@Autowired
private EmailService emailService;
@Autowired
private Utils utils;
public Boolean sendFactura(int id, MailFacturaDTO dto) {
try {
Factura factura = getById(id);
Cliente cliente = factura.getIdCliente();
String destinatario = cliente.getEmail();
String remitente = "Remitente";
if(dto.getRemitente() != null)
remitente = dto.getRemitente();
String asunto = "Tu factura de " + Utils.traduceMes(factura.getFecha().getMonth()) + " de " + remitente;
if(dto.getAsunto() != null)
asunto = dto.getAsunto();
String nombre = cliente.getNombre();
if(cliente.getApellidos() != null && !cliente.getApellidos().isBlank())
nombre = nombre + " " + cliente.getApellidos();
String template = "envioFactura";
File file = utils.convert(dto.getFile(), "factura.pdf");
Map<String,Object> props = new HashMap<>();
props.put("nombre", nombre);
props.put("remitente", remitente);
if(destinatario != null && !destinatario.isBlank()) {
emailService.send(props, destinatario, file, template, nombre, asunto);
factura.setEstado(EstadoFactura.ENVIADO);
facturaRepository.save(factura);
return true;
}
return false;
} catch(Exception e) {
System.out.println(e.getMessage());
return false;
}
}
AND THE EMAILSERVICE CLASS
@Service
public class EmailService {
@Autowired
private TemplateTool templateTool;
@Autowired
private MailTool mailTool;
public void send(Map<String, Object> props, String email, File file, String template, String projectName, String subject) throws Exception {
List<String> emailList = new ArrayList<>();
emailList.add(email);
List<File> files = new ArrayList<>();
files.add(file);
String render = templateTool.render(template, props);
DataBuilder mailData = Data.builder().body(render).from("[email protected]")
.fromName(projectName)
.subject(subject)
.fileList(files)
.targetList(emailList);
Data mailDataBuild = mailData.build();
mailTool.send(mailDataBuild, null);
Files.deleteIfExists(file.toPath());
}
}
After a lot of unsuccessful testing, such as trying to make the method calls involved in the mailing process asynchronous, someone who knows a lot more than me (my boss) has fixed it.
The solution has been that instead of...
Now I do...
With which, a different pdf file is being generated for each call and now a call does not crush the file that was still being generated for the previous call.
How easy the solution was, and how difficult and frustrating it was for me.
Thank you all for trying to help me.