2016-07-01 24 views
5

我試圖使用SpEL模板從實體生成文件名。 我有類似於這兩個實體: 春季表達語言(SpEL)不適用於JPA /休眠實體

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

而且類似於規劃環境地政司模板,這一個:

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

然後我使用規劃環境地政司以產生從模板帶發票對象的文件名

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

這個測試工作:

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

本次測試沒有:

Invoice invoice = invoiceRepository.findOne(4); 

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

這個測試實際上會導致「12344-201601-」,這使我的假設,即用於延遲加載客戶對象休眠代理是問題。 firstname和lastname字段在從數據庫加載之前爲null,這將解釋呈現的文件名。

有關如何解決此問題的任何想法?有些事情我已經嘗試過:

Hibernate.initialize(invoice); 
Hibernate.initialize(invoice.getCustomer()); 
System.out.println(invoice.getCustomer().getFirstname()); 
  • 在表達式中使用 「customer.getFirstname()」 而不是 「customer.firstname」
  • @Transactional添加到我的FilenameGenerator類
+0

如果您使用FetchType.EAGER,它會工作嗎?我的意思是,我希望它能以任何方式工作,但它可能有助於確認SpEL是否不正確使用延遲加載代理 –

回答

1

的問題在別的地方,SpEL和JPA/Hibernate一起工作得很好。對不起!

我的實際表現是這樣的:

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

可悲的是這是從數據庫加載也有一個公司,一個空的公司... 有了下面的表達式一切客戶工作出正確:

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