5 votes

Le langage d'expression Spring (SpEL) ne fonctionne pas sur une entité JPA/hibernate

J'essaie d'utiliser un modèle SpEL pour générer des noms de fichiers à partir d'entités. J'ai deux entités qui ressemblent à celles-ci :

@Entity
public class Invoice implements Serializable {
    private String invoicenumber;
    private Customer customer;

    @Column(name = "invoicenumber", nullable = false, length = 20)
    public String getInvoicenumber() {
        return this.invoicenumber;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "fk_customer", nullable = false)
    public Customer getCustomer() {
        return this.customer;
    }
}

@Entity
public class Customer implements Serializable {
    private String firstname;
    private String lastname;

    @Column(name = "firstname", nullable = false, length = 20)
    public String getFirstname() {
        return this.firstname;
    }

    @Column(name = "lastname", nullable = false, length = 20)
    public String getLastname() {
        return this.lastname;
    }
}

Et un modèle SpEL similaire à celui-ci :

String template = "invoicenumber + '-' + customer.firstname + ' ' + customer.lastname";

Ensuite, j'utilise SpEL pour générer un nom de fichier à partir du modèle avec un objet facture.

public String generateFilename(String filenameTemplate, Object dataObject) {
    ExpressionParser parser = new SpelExpressionParser();
    Expression expression = parser.parseExpression(filenameTemplate);
    return expression.getValue(dataObject, String.class);
}

Ce test fonctionne :

String testTemplate = "invoicenumber + '-' + customer.firstname + ' ' + customer.lastname";
Invoice invoice = new Invoice();
invoice.setInvoicenumber("BF2016-06-ABCDEF");
invoice.setCustomer(new Customer());
invoice.getCustomer().setFirstname("Hans");
invoice.getCustomer().setLastname("Hansen");
assertEquals("BF2016-06-ABCDEF-Hans Hansen", generator.generateFilename(testTemplate, invoice));

Ce test ne le fait pas :

Invoice invoice = invoiceRepository.findOne(4);

String template = "invoicenumber + '-' + customer.firstname + ' ' + customer.lastname";
String filename = filenameGenerator.generateFilename(template, invoice);
assertEquals("12344-201601-Heinrich Jahnke", filename);

Ce test donne en fait "12344-201601-", ce qui m'amène à supposer que les proxies hibernate utilisés pour le chargement paresseux de l'objet client sont à l'origine du problème. Les champs prénom et nom sont nuls avant d'être chargés depuis la base de données, ce qui expliquerait le nom de fichier rendu.

Avez-vous des idées sur la façon de résoudre ce problème ? J'ai déjà essayé certaines choses :

Hibernate.initialize(invoice);
Hibernate.initialize(invoice.getCustomer());
System.out.println(invoice.getCustomer().getFirstname());
  • Utilisation de "customer.getFirstname()" au lieu de "customer.firstname" dans l'expression
  • Ajout de @Transactional à ma classe FilenameGenerator

1voto

Stefan Erichsen Points 179

Le problème était ailleurs, SpEL et JPA/Hibernate fonctionnent bien ensemble. Je suis désolé pour cela !

Mon expression réelle ressemblait à ceci :

"invoicenumber + '-' + (customer.company == null ? customer.fname + ' ' + customer.sname : customer.company)"

Malheureusement, le client qui a été chargé depuis la base de données avait bien une société, une société vide... Avec l'expression suivante, tout fonctionne correctement :

"invoicenumber + '-' + (customer.company == null or customer.company.isEmpty() ? customer.fname + ' ' + customer.sname : customer.company)"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X