繁体   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