I am trying to use the SpEL pattern to generate a file name from entities. I have two objects that look something like this:
@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; } }
And a SpEL template like this:
String template = "invoicenumber + '-' + customer.firstname + ' ' + customer.lastname";
Then I use SpEL to create a file name from a template with an account object
public String generateFilename(String filenameTemplate, Object dataObject) { ExpressionParser parser = new SpelExpressionParser(); Expression expression = parser.parseExpression(filenameTemplate); return expression.getValue(dataObject, String.class); }
This test works:
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));
In this test, no:
Invoice invoice = invoiceRepository.findOne(4); String template = "invoicenumber + '-' + customer.firstname + ' ' + customer.lastname"; String filename = filenameGenerator.generateFilename(template, invoice); assertEquals("12344-201601-Heinrich Jahnke", filename);
This test actually leads to "12344-201601-", which leads me to speculate that the sleep mode problems used to lazily load the client object are a problem. The firstname and lastname fields are null before they are loaded from the database, which explains the display name of the file.
Any ideas on how to fix this? Some things that I have already tried:
Hibernate.initialize(invoice); Hibernate.initialize(invoice.getCustomer()); System.out.println(invoice.getCustomer().getFirstname());
- Using "customer.getFirstname ()" instead of "customer.firstname" in the expression
- Adding @Transactional to my FilenameGenerator class