java - 通过实体图加载元素集合时,SqlNode 的文本没有引用预期的列数错误
问题描述
我有一个发票实体,其中包括帐单、送货地址、客户等,还保存付款和发票行项目。我正在使用命名实体图为我定义的每个自定义存储库方法加载不同的关联。
发票类
@Slf4j
@Entity
@Setter
@Getter
@ToString
@NoArgsConstructor
@Where(clause = "DELETED = 0")
@Relation(collectionRelation = "invoices")
@Table(indexes = { @Index(name = "place_of_supply_index", columnList = "placeOfSupply", unique = false),
@Index(name = "invoice_date_index", columnList = "invoiceDate", unique = false),
@Index(name = "due_date_index", columnList = "dueDate", unique = false),
@Index(name = "payment_terms_index", columnList = "paymentTerms", unique = false) })
@NamedEntityGraphs({
@NamedEntityGraph(name = "invoice_customer_details", attributeNodes = { @NamedAttributeNode("customer") }),
@NamedEntityGraph(name = "invoice_details", attributeNodes = { @NamedAttributeNode("customer"),
@NamedAttributeNode("billedTo"), @NamedAttributeNode("shippedTo") }),
@NamedEntityGraph(name = "invoice_billing_details", attributeNodes = { @NamedAttributeNode("lineItems"),
@NamedAttributeNode("payments") }),
@NamedEntityGraph(name = "invoice_all_details", attributeNodes = { @NamedAttributeNode("customer"),
@NamedAttributeNode("billedTo"), @NamedAttributeNode("shippedTo"), @NamedAttributeNode("lineItems"),
@NamedAttributeNode("payments") }), })
public class Invoice extends AuditableEntity implements Identifiable<Long>, Serializable {
private static final long serialVersionUID = 1560474818107754225L;
@NotEmpty(message = "Cannot save invoice without Invoice Number")
//@NaturalId
@Column(unique = true, length = 20, nullable = false, updatable = false)
private String invoiceNumber;
@JsonIgnore
private Integer deleted = 0;
@NotEmpty(message = "Cannot save invoice without Line Items")
@ElementCollection(fetch = FetchType.LAZY)
@CollectionTable(name = "invoice_line_items", joinColumns = @JoinColumn(name = "invoice_id"))
@JsonInclude(value = Include.NON_EMPTY, content = Include.NON_NULL)
@OrderBy("serialNumber ASC")
private Set<LineItem> lineItems;
@ElementCollection(fetch = FetchType.LAZY)
@CollectionTable(name = "invoice_payments", joinColumns = @JoinColumn(name = "invoice_id"))
@JsonInclude(value = Include.NON_EMPTY, content = Include.NON_NULL)
@OrderBy("paymentDate DESC")
private Set<Payment> payments;
在存储库类中,我定义了一个方法来查找给定客户的所有已付款发票,并使用要加载的实体图Payments
和LineItems
@Lock(LockModeType.OPTIMISTIC)
@EntityGraph(value = "invoice_billing_details", type = EntityGraphType.LOAD)
Page<Invoice> findByPaymentsIsNotNullAndCustomer_Id(Long id, Pageable pageable);
此方法抛出异常
org.springframework.orm.jpa.JpaSystemException: SqlNode's text did not reference expected number of columns; nested exception is org.hibernate.HibernateException: SqlNode's text did not reference expected number of columns
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:312)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:223)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:527)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy149.findByPaymentsIsNotNullAndCustomer_Id(Unknown Source)
我不知道如何解决这个问题。这是由于错误而失败的测试
@Test
public void testFindAllPaidInvoicesByCustomer() throws Exception {
//other invoice fields are set in the @Before annotated setup method
invoice.setDueDate(Date.from(LocalDate.now().minusDays(10).atStartOfDay(ZoneId.of("Asia/Kolkata")).toInstant()));
invoice.setPaymentTerms("NET-30");
invoice
.setInvoiceDate(Date.from(LocalDate.now().minusDays(40).atStartOfDay(ZoneId.of("Asia/Kolkata")).toInstant()));
Set<Payment> payments = new HashSet<>();
payments.add(getPayment());
invoice.setPayments(payments);
invoice.setLineItems(builder.getInvoiceObjectWithLineItems().getLineItems());
Invoice savedInvoice = invoiceRepository.saveAndFlush(invoice);
em.clear();
Page<Invoice> invoices = invoiceRepository.findByPaymentsIsNotNullAndCustomer_Id(savedInvoice.getCustomer().getId(),
PageRequest.of(0, 10));
assertThat(invoices).isNotEmpty();
assertThat((new ArrayList<>(invoices.getContent())).get(0).getId()).isEqualTo(savedInvoice.getId());
}
解决方案
错误是由于private Integer deleted = 0;
添加了列映射并解决了它。
@JsonIgnore
@Column(nullable = false)
@ColumnDefault("0")
private Integer deleted = 0;
推荐阅读
- ruby - Ruby:链接方法给出不同的结果:.chars.pop
- python - 使用 csv 阅读器读取数值数据
- mysql - 在 case 语句中聚合数据
- apache-kafka - “Kafka消费组授权失败。” 偶尔?
- string - uint32_t 等价于字符串和其他数据类型
- azure - Azure ACR 任务无法从 Azure 容器注册表中提取 docker 映像
- swift - 如何设置通知的期限(时间段)?
- python - 在新行中结合 csv 和 Python
- sql - SQL 使用 0 行 from where 0 rows to group by 而不是什么都没有
- latex - 带点和逗号的乳胶十进制和千位分隔符