3

我的数据模型是

 @Getter
 @Setter
 public class Customer {
   @Id private ID id;
   @CreatedDate protected Instant createdAt;
   @LastModifiedDate protected Instant updatedAt;
   @CreatedBy protected String createdBy;
   @LastModifiedBy protected String updatedBy;
   @Version protected Long version;
   private UUID orderId;
   private String offer;
}

我的存储库是

public interface CustomerRepository extends CrudRepository<Customer, UUID> {

@Query(
        "SELECT ID, Offer  FROM Customer WHERE orderId = :orderId ")
List<Customer> findCustomerByOrderId(
        @Param("orderId") UUID orderId);
}

这将导致异常说'orderId column not found [42122-190]'。所以 Spring 期望你总是查询所有的列。我知道使用 JPA,我们在实体和数据模式之间建立了强大的映射关系。但是 Spring Data JDBC 的重点是避免 POJO 的数据模型和数据库模式之间的紧密耦合。为什么 EntityRowMapper 不只是映射NULL到不属于查询的属性?

有没有办法告诉使用的 RowMapper 忽略不属于查询的属性?为这些简单的查询单独创建RowMapper似乎是很多不必要的工作。

我仍然可以通过更改查询来解决这个问题

@Query(
        "SELECT ID, Offer, OrderId, null as CreatedAt, null as CreatedBy, null as UpdatedAt, null as UpdatedBy, null as Version  FROM Customer  WHERE orderId = :orderId ")

但这仍然会用空值序列化整个对象。我在这里遗漏了一些明显的东西吗?

注意这不是 Spring Data JPA。它的 Spring Data JDBC。

编辑 更深入地研究它,例外是来自 h2 数据库库。

Caused by: org.h2.jdbc.JdbcSQLException: Column "orderid" not found [42122-190]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.jdbc.JdbcResultSet.getColumnIndex(JdbcResultSet.java:3129)
at org.h2.jdbc.JdbcResultSet.get(JdbcResultSet.java:3217)
at org.h2.jdbc.JdbcResultSet.getObject(JdbcResultSet.java:522)
at com.zaxxer.hikari.pool.HikariProxyResultSet.getObject(HikariProxyResultSet.java)
at org.springframework.data.jdbc.core.EntityRowMapper.readFrom(EntityRowMapper.java:127)
4

1 回答 1

3

你至少现在不能。

对此有三个解决方案,您已经指出了其中两个:

  1. , NULL as <column-name>为所有缺失的列扩展您的选择语句。

    我不确定是否

    但这仍然会用空值序列化整个对象。

意味着这在某种程度上不适合你。

  1. 指定一个RowMapper.
  2. 您可以使用一个包含查询返回的字段的类。如果您想要一个由您的普通实体和部分实体实现的接口,它甚至可以为其他列提供 getter 。

你写:

但是spring data JDBC的重点是避免pojo的数据模型和数据库模式之间的紧密耦合。

这不太对。Spring Data JDBC 的一个重要目标是在实体和表行之间没有运行时连接。这将需要代理或类似的,并带来很多复杂性。但是实体和表之间的结构映射可能会变得更强大(当然现在也是如此),因为 JPA 中可用的所有映射变体都带来了复杂性。Spring Data JDBC 的主要目标是在概念上比 JPA 更简单。

你也问

为什么 EntityRowMapper 不只是将 NULL 映射到不属于查询的属性?

我不确定我在编写代码时是否主动考虑过它,但我不喜欢默认为的想法,NULL因为这样很容易意外地不加载列,因为别名中有错字。

但我并不反对替代解决方案。如果您有想法,请创建功能请求

于 2019-03-14T06:52:19.910 回答