簡體   English   中英

JPA 查詢對不在查詢中的列拋出“未找到”錯誤

[英]JPA query is throwing a 'not found' error for column that isn't in query

我試圖只調用我的數據庫中的特定列,但查詢拋出一個錯誤,指出找不到下一列(即使它不在查詢中)

這樣做的加入有問題嗎? 我對這個問題有點困惑。

JPA 從 ConnectionRequestRepository 查詢 -

@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();
}

Controller -

ConnectionRequest currentLocationRequest = connectionRequestService.getActiveRequestToCaller();

連接請求 Class -

@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;
}

}

錯誤圖片

Since you are mapping your native query to entity object, hibernate finds out that is an entity object due to all these annotation and everything, it is checking if this object is in persistence context cache or not.

因此,它沒有找到它並創建一個,但隨后它嘗試 map 查詢結果集到此實體 object 但在映射時它沒有找到所有列來初始化實體(注意這里的列是預期但如果值為 null 它可能工作)。

但是,如果提供了所有列,則可以將 map 轉換為實體 object。

讓我舉個例子,假設我有這個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.stackoverflow.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.stackoverflow.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

在這種情況下,它成功轉換。

解決您的問題

因此,如果您想使用要返回的實體,則必須提供所有字段,否則您可以使用界面投影或這個問題建議的東西

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM