2016-07-01 16 views
5

Ich versuche, eine SpEL-Vorlage zu verwenden, um Dateinamen aus Entitäten zu generieren. Ich habe zwei Entitäten, die auf diese aussehen: Spring Expression Language (SpEL) funktioniert nicht auf JPA/Hibernate-Entität

@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; 
    } 
} 

Und eine Spel Vorlage ähnlich wie diese:

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

dann verwende ich Spel einen Dateinamen aus der Vorlage mit einer Rechnung Objekt zu erzeugen,

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

Dieser Test funktioniert:

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)); 

Dieser Test nicht:

Invoice invoice = invoiceRepository.findOne(4); 

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

Dieser Test tatsächlich zu „12344-201601-“, was mich zu der Annahme führt, dass die Hibernate Proxies für verzögertes Laden sind das Kundenobjekt verwenden das Problem . Die Felder Vorname und Nachname sind NULL, bevor sie von der Datenbank geladen werden, was den gerenderten Dateinamen erklären würde.

Irgendwelche Ideen, wie Sie das beheben können? Ich einige Dinge schon versucht:

Hibernate.initialize(invoice); 
Hibernate.initialize(invoice.getCustomer()); 
System.out.println(invoice.getCustomer().getFirstname()); 
  • Mit "customer.getFirstname()" statt "Customer.FirstName" im Ausdruck
  • Hinzufügen @Transactional meiner FilenameGenerator Klasse
+0

Funktioniert es, wenn Sie FetchType.EAGER verwenden? Ich meine, ich würde erwarten, dass es so oder so funktioniert, aber es könnte helfen zu bestätigen, ob der SpEL die Lazy Loading Proxies nicht korrekt verwendet –

Antwort

1

Die Problem war woanders, SpEL und JPA/Hibernate arbeiten gut zusammen. Das tut mir leid!

Mein eigentlicher Ausdruck sah dies wie:

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

Leider der Kunde, die aus der Datenbank geladen wurden eine Firma hatte, ein leeres Unternehmen ... Mit folgendem Ausdruck funktioniert alles richtig aus:

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