2016-07-01 28 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)"