JPA 查询对不在查询中的列抛出“未找到”错误
Posted
技术标签:
【中文标题】JPA 查询对不在查询中的列抛出“未找到”错误【英文标题】:JPA query is throwing a 'not found' error for column that isn't in query 【发布时间】:2021-07-04 15:50:12 【问题描述】:我试图只调用我的数据库中的特定列,但查询抛出一个错误,指出未找到下一列(即使它不在查询中)
执行此操作的连接有问题吗?我对这个问题有点困惑。
来自 ConnectionRequestRepository 的 JPA 查询 -
@Query(value = "SELECT connection_request.id, connection_request.userId, connection_request.dateTimeCompleted, connection_request.phoneNumber " +
"FROM ***.connection_request " +
"INNER JOIN ***.user " +
"ON ***.connection_request.userID = ***.user.id " +
"WHERE connection_request.dateTimeCompleted IS NULL " +
"LIMIT 1", nativeQuery = true)
ConnectionRequest findActiveRequest();
服务-
public ConnectionRequest getActiveRequestToCaller()
return connectionRequestRepository.findActiveRequest();
控制器 -
ConnectionRequest currentLocationRequest = connectionRequestService.getActiveRequestToCaller();
ConnectionRequest 类 -
@Entity
@Table(name = "connection_request")
public class ConnectionRequest
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
@NotNull
private Long id;
@Column(name = "userId")
@NotNull
private Long userId;
@Column(name = "uuid")
@NotNull
private UUID uuid;
@Column(name = "phoneNumber")
@NotNull
private String phoneNumber;
@Column(name = "locationSource")
@NotNull
private String locationSource;
@Column(name = "dateTimeRequested")
private Timestamp dateTimeRequested;
@Column(name = "dateTimeRequestExpires")
private Timestamp dateTimeRequestExpires;
@Column(name = "dateTimeCompleted")
private Timestamp dateTimeCompleted;
@Column(name = "s3Bucket")
private String s3Bucket;
@Column(name = "s3Key")
private String s3Key;
@Column(name = "s3Etag")
private String s3Etag;
@Column(name = "s3Sha256Hash")
private String s3Sha256Hash;
@Column(name = "isScheduledForCompletion")
@NotNull
private Integer isScheduledForCompletion;
public ConnectionRequest()
public ConnectionRequest(Long id,
Long userId,
UUID uuid,
String phoneNumber,
String locationSource,
Timestamp dateTimeRequested,
Timestamp dateTimeRequestExpires,
Timestamp dateTimeCompleted,
String s3Bucket,
String s3Key,
String s3Etag,
String s3Sha256Hash,
Integer isScheduledForCompletion)
this.id = id;
this.userId = userId;
this.uuid = uuid;
this.phoneNumber = phoneNumber;
this.locationSource = locationSource;
this.dateTimeRequested = dateTimeRequested;
this.dateTimeRequestExpires = dateTimeRequestExpires;
this.dateTimeCompleted = dateTimeCompleted;
this.s3Bucket = s3Bucket;
this.s3Key = s3Key;
this.s3Etag = s3Etag;
this.s3Sha256Hash = s3Sha256Hash;
this.isScheduledForCompletion = isScheduledForCompletion;
public Long getId()
return id;
public void setId(Long id)
this.id = id;
public Long getUserId()
return userId;
public void setUserId(Long userId)
this.userId = userId;
public UUID getUuid()
return uuid;
public void setUuid(UUID uuid)
this.uuid = uuid;
public String getPhoneNumber()
return phoneNumber;
public void setPhoneNumber(String phoneNumber)
this.phoneNumber = phoneNumber;
public String getLocationSource()
return locationSource;
public void setLocationSource(String locationSource)
this.locationSource = locationSource;
public Timestamp getDateTimeRequested()
return dateTimeRequested;
public void setDateTimeRequested(Timestamp dateTimeRequested)
this.dateTimeRequested = dateTimeRequested;
public Timestamp getDateTimeRequestExpires()
return dateTimeRequestExpires;
public void setDateTimeRequestExpires(Timestamp dateTimeRequestExpires)
this.dateTimeRequestExpires = dateTimeRequestExpires;
public Timestamp getDateTimeCompleted()
return dateTimeCompleted;
public void setDateTimeCompleted(Timestamp dateTimeCompleted)
this.dateTimeCompleted = dateTimeCompleted;
public String getS3Bucket()
return s3Bucket;
public void setS3Bucket(String s3Bucket)
this.s3Bucket = s3Bucket;
public String getS3Key()
return s3Key;
public void setS3Key(String s3Key)
this.s3Key = s3Key;
public String getS3Etag()
return s3Etag;
public void setS3Etag(String s3Etag)
this.s3Etag = s3Etag;
public String getS3Sha256Hash()
return s3Sha256Hash;
public void setS3Sha256Hash(String s3Sha256Hash)
this.s3Sha256Hash = s3Sha256Hash;
public Integer getIsScheduledForCompletion()
return isScheduledForCompletion;
public void setIsScheduledForCompletion(Integer isScheduledForCompletion)
this.isScheduledForCompletion = isScheduledForCompletion;
【问题讨论】:
什么是ConnectionRequest
对象?
@code_mechanic 这是数据库的名称。我是 JPA 查询的新手。我假设我写错了?
你将哪个类映射到 connection_request 表?
@MatheusCirillo 实体表(name = "connection_request") 公共类 ConnectionRequest
编辑问题并发布您的整个ConnectionRequest
课程。我认为问题是由于本机查询而发生的。所以,可以肯定的是,我必须看到ConnectionRequest
类。 . .
【参考方案1】:
由于您将本机查询映射到实体对象,由于所有这些注释和所有内容,hibernate 会发现这是一个实体对象,它正在检查该对象是否在 persistence context 缓存中.
因此,它没有找到它并创建一个,但随后它尝试将查询中的结果集映射到此实体对象,但在映射时它没有找到所有列来初始化实体(注意这里的列是预期的,但如果值为 null,它可能会起作用)。
但是,如果提供了所有列,它就可以映射到实体对象。
让我举个例子,假设我有这个Car
实体
@Entity
@Table(name = "car")
public class Car
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@NotBlank(message = "car name`s must be not empty")
private String name;
@Column(name = "production_year", nullable = false)
private LocalDateTime productionYear;
private boolean tested;
@ManyToOne
@JoinColumn(name = "brand_id")
private Brand brand;
我的存储库方法是这样的
@Query(value = "select id, name, brand_id, production_year from car", nativeQuery = true)
List<Car> findAllCars();
注意tested
不存在,所以hibernate 发出同样的错误
could not execute query [select id, name, brand_id, production_year from car]
java.sql.SQLException: Column 'tested' not found.
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129) ~[mysql-connector-java-8.0.23.jar:8.0.23]
但如果我包含tested
@Query(value = "select id, name, brand_id, production_year, tested from car", nativeQuery = true)
List<Car> findAllCars();
Hibernate 会这样做
: Unable to locate native-sql query plan in cache; generating (select id, name, brand_id, production_year, tested from car)
2021-04-09 00:54:02.143 TRACE 40352 --- [nio-8080-exec-2] o.h.loader.custom.sql.SQLCustomQuery : Starting processing of sql query [select id, name, brand_id, production_year, tested from car]
2021-04-09 00:54:02.198 TRACE 40352 --- [nio-8080-exec-2] o.h.l.c.sql.SQLQueryReturnProcessor : Mapping alias [alias1] to entity-suffix [0_]
2021-04-09 00:54:02.206 TRACE 40352 --- [nio-8080-exec-2] org.hibernate.internal.SessionImpl : SQL query: select id, name, brand_id, production_year, tested from car
2021-04-09 00:54:02.223 DEBUG 40352 --- [nio-8080-exec-2] org.hibernate.SQL : select id, name, brand_id, production_year, tested from car
Hibernate: select id, name, brand_id, production_year, tested from car
2021-04-09 00:54:02.364 TRACE 40352 --- [nio-8080-exec-2] o.h.r.j.i.ResourceRegistryStandardImpl : Registering statemen
如果你再往下看,它会给出这样的结果
: Object not resolved in any cache: [com.example.***.model.Brand#1]
2021-04-09 00:54:02.559 TRACE 40352 --- [nio-8080-exec-2] o.h.p.entity.AbstractEntityPersister : Fetching entity: [com.example.***.model.Brand#1]
2021-04-09 00:54:02.560 DEBUG 40352 --- [nio-8080-exec-2] org.hibernate.SQL : select brand0_.id as id1_0_0_, brand0_.name as name2_0_0_, brand0_.production_year as producti3_0_0_ from brand brand0_ where brand0_.id=?
Hibernate: select brand0_.id as id1_0_0_, brand0_.name as name2_0_0_, brand0_.production_year as producti3_0_0_ from brand brand0_ where brand0_.id=?
2021-04-09 00:54:02.562 TRACE 40352 --- [nio-8080-exec-2] o.h.r.j.i.ResourceRegistryStandardImpl : Registering statement [HikariProxyPreparedStatement
在这种情况下它成功转换。
解决您的问题
因此,如果您想使用要返回的实体,则必须提供所有字段,否则您可以使用界面投影或question 建议的东西
【讨论】:
完美解释!非常感谢! 一般原生查询,我一直使用自定义DTO或者界面投影(字段较小),所以尽量避免原生查询实体转换。以上是关于JPA 查询对不在查询中的列抛出“未找到”错误的主要内容,如果未能解决你的问题,请参考以下文章