Spring 表达式语言 (SpEL) 不适用于 JPA/hibernate 实体
Spring expression language (SpEL) not working on JPA/hibernate entity
我正在尝试使用 SpEL 模板从实体生成文件名。
我有两个看起来与这些相似的实体:
@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;
}
}
还有一个类似于这个的 SpEL 模板:
String template = "invoicenumber + '-' + customer.firstname + ' ' + customer.lastname";
然后我使用 SpEL 从带有发票对象的模板生成文件名
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 字段在从数据库加载之前为空,这将解释呈现的文件名。
关于如何解决这个问题有什么想法吗?有些事情我已经尝试过:
Hibernate.initialize(invoice);
Hibernate.initialize(invoice.getCustomer());
System.out.println(invoice.getCustomer().getFirstname());
- 在表达式中使用 "customer.getFirstname()" 而不是 "customer.firstname"
- 将@Transactional 添加到我的 FilenameGenerator class
问题出在其他地方,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)"
我正在尝试使用 SpEL 模板从实体生成文件名。 我有两个看起来与这些相似的实体:
@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;
}
}
还有一个类似于这个的 SpEL 模板:
String template = "invoicenumber + '-' + customer.firstname + ' ' + customer.lastname";
然后我使用 SpEL 从带有发票对象的模板生成文件名
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 字段在从数据库加载之前为空,这将解释呈现的文件名。
关于如何解决这个问题有什么想法吗?有些事情我已经尝试过:
Hibernate.initialize(invoice);
Hibernate.initialize(invoice.getCustomer());
System.out.println(invoice.getCustomer().getFirstname());
- 在表达式中使用 "customer.getFirstname()" 而不是 "customer.firstname"
- 将@Transactional 添加到我的 FilenameGenerator class
问题出在其他地方,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)"