2016-07-01 11 views
5

Próbuję użyć szablonu SpEL do wygenerowania nazwy pliku z encji. Mam dwa podmioty, które wyglądają podobnie do tych: Język wyrażeń Spring (Spel) nie działa na jednostce JPA/hibernacji

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

i szablon Spel podobny do tego:

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

potem użyć Spel w celu wygenerowania pliku z szablonem z obiektem faktury

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

badanie to działa:

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

Ten test nie:

Invoice invoice = invoiceRepository.findOne(4); 

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

Ten test faktycznie skutkuje „12344-201601-”, który prowadzi mnie do założenia, że ​​proxy hibernacji wykorzystywane do leniwego ładowania obiektu klienta są problemem . Pola imienia i nazwiska są puste, zanim zostaną załadowane z bazy danych, co tłumaczy renderowaną nazwę pliku.

Wszelkie pomysły na rozwiązanie tego problemu? niektóre rzeczy ja już próbowałem:

Hibernate.initialize(invoice); 
Hibernate.initialize(invoice.getCustomer()); 
System.out.println(invoice.getCustomer().getFirstname()); 
  • Używanie "customer.getFirstname()" zamiast "customer.firstname" w wyrażeniu
  • Dodawanie @Transactional do mojej klasy FilenameGenerator
+0

Czy to działa, jeśli używasz FetchType.EAGER? Chodzi mi o to, że spodziewałbym się, że to zadziała, ale może to pomóc w sprawdzeniu, czy Spel nie używa poprawnie leniwych serwerów ładujących –

Odpowiedz

1

problem był gdzieś indziej, Spel i JPA/Hibernate działają dobrze razem. Przepraszam za to!

Mój rzeczywisty wyraz wyglądał następująco:

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

Niestety klient, który został załadowany z bazy miał firmę, pusty firmę ... Z następujące wyrażenie wszystko działa poprawnie:

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