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