存储库中按方法名称进行的 Spring 数据 JPA 查询无效。如何在涉及这样的 AND 条件的情况下检索对象列表?
Invalid Spring Data JPA query by method name in a repository. How to retrieve a list of object in a situation involving an AND condition like this?
我正在处理一个涉及 Hibernate 和 Spring Data JPA 的 Spring 引导项目,我在尝试使用按方法名称样式的查询来实现查询时遇到以下问题。
我试着向你详细解释一下我的情况:
我有一个名为 TransactionStatusLog:
的主要实体 class
@Entity
@Table(name = "transaction_status_log")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class TransactionStatusLog {
@Id
@Column(name = "id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@Column(name = "reason")
private String reason;
@Column(name = "is_active")
Boolean isActive;
@Column(name = "created_at",columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
private Date createdAt;
@ManyToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "transaction_id_fk", referencedColumnName = "id")
private TransactionLog transactionLog;
@ManyToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "transaction_status_type_id_fk", referencedColumnName = "id")
private TransactionStatusType transactionStatusType;
// The admin that changes the status:
@OneToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "user_id_fk", referencedColumnName = "id")
private User user;
}
如您所见,它包含此 多对一 关系:
@ManyToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "transaction_id_fk", referencedColumnName = "id")
private TransactionLog transactionLog;
遵循 TransactionLog 实体 class 代码:
@Entity
@Table(name = "transaction")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class TransactionLog implements Serializable {
@Id
@Column(name = "id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@ManyToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "source_user_fk", referencedColumnName = "id")
//@JsonManagedReference(value = "sourceUser")
private User sourceUser;
@ManyToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "destination_user_fk", referencedColumnName = "id")
private User destinationUser;
@ManyToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "source_wallet_fk", referencedColumnName = "id")
private Wallet sourceWallet;
@ManyToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "destination_wallet_fk", referencedColumnName = "id")
private Wallet destinationWallet;
@Column(name = "notes")
private String notes;
@Column(name = "timestamp",columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
private Date timestamp;
@Column(name = "amount")
private BigDecimal amount;
@ManyToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "log_type_fk", referencedColumnName = "id")
//@Column(name = "log_type_fk")
private LogType logType;
@ManyToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "fk_network", referencedColumnName = "id")
private Network network;
@ManyToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "fk_chain", referencedColumnName = "id")
private Chain chain;
}
然后我有一个在我的主要 TransactionStatusLog 实体 class.
上工作的存储库接口
public interface TransactionStatusLogRepository extends JpaRepository<TransactionStatusLog, Integer>, JpaSpecificationExecutor {
TransactionStatusLog findById(String id);
List<TransactionStatusLog> findByTransactionLog_Id(Integer transactionId);
List<TransactionStatusLog> findByIsActiveAndTransactionLog_Id(Integer transactionId);
我创建了最后一个方法定义:
List<TransactionStatusLog> findByIsActiveAndTransactionLog_Id(Integer transactionId);
尝试执行以下查询:查找所有 TransactionStatusLog 具有:
- Boolean isActive 字段的值为 true
- 并使 TransactionLog(第二个实体 class)具有特定的 ID 值。
最后我创建了这个 JUnit 测试方法来测试这个存储库查询:
@Test
@Order(3)
@Transactional
public void findByIsActiveAndTransactionLog_IdTest() {
List<TransactionStatusLog> result = this.transactionStatusLogRepository.findByIsActiveAndTransactionLog_Id(37);
assertTrue(result.size() == 1, "The result contains 1 tactive transaction status changes related to the transaction having ID: 37");
}
问题是 运行 这个测试方法(它没有启动,因为我的 Spring Data JPA query by name 方法定义似乎是错误的)我在我的堆栈跟踪中得到这个异常:
Caused by: org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract java.util.List com.easydefi.users.repository.TransactionStatusLogRepository.findByIsActiveAndTransactionLog_Id(java.lang.Integer)! Reason: Failed to create query for method public abstract java.util.List
我的代码有什么问题?我该如何修复它? (如果按名称方法查询对于这样的用例来说太复杂,也可以使用 JPQL)
您能否通过添加“True”并删除下划线来重试。它应该看起来像 ->
List<TransactionStatusLog> result = this.transactionStatusLogRepository.findByIsActiveTrueAndTransactionLogId(37);
List<TransactionStatusLog> findByIsActiveAndTransactionLog_Id(Integer transactionId);
应该接受两个参数。一份用于 isActive
一份用于 transactionLogId
.
正确的形式是:
List<TransactionStatusLog> findByIsActiveAndTransactionLog_Id(boolean isActive, Integer transactionId);
然后调用:
List<TransactionStatusLog> result = transactionStatusLogRepository.findByIsActiveAndTransactionLog_Id(true, 37);
我正在处理一个涉及 Hibernate 和 Spring Data JPA 的 Spring 引导项目,我在尝试使用按方法名称样式的查询来实现查询时遇到以下问题。
我试着向你详细解释一下我的情况:
我有一个名为 TransactionStatusLog:
的主要实体 class@Entity
@Table(name = "transaction_status_log")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class TransactionStatusLog {
@Id
@Column(name = "id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@Column(name = "reason")
private String reason;
@Column(name = "is_active")
Boolean isActive;
@Column(name = "created_at",columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
private Date createdAt;
@ManyToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "transaction_id_fk", referencedColumnName = "id")
private TransactionLog transactionLog;
@ManyToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "transaction_status_type_id_fk", referencedColumnName = "id")
private TransactionStatusType transactionStatusType;
// The admin that changes the status:
@OneToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "user_id_fk", referencedColumnName = "id")
private User user;
}
如您所见,它包含此 多对一 关系:
@ManyToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "transaction_id_fk", referencedColumnName = "id")
private TransactionLog transactionLog;
遵循 TransactionLog 实体 class 代码:
@Entity
@Table(name = "transaction")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class TransactionLog implements Serializable {
@Id
@Column(name = "id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@ManyToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "source_user_fk", referencedColumnName = "id")
//@JsonManagedReference(value = "sourceUser")
private User sourceUser;
@ManyToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "destination_user_fk", referencedColumnName = "id")
private User destinationUser;
@ManyToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "source_wallet_fk", referencedColumnName = "id")
private Wallet sourceWallet;
@ManyToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "destination_wallet_fk", referencedColumnName = "id")
private Wallet destinationWallet;
@Column(name = "notes")
private String notes;
@Column(name = "timestamp",columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
private Date timestamp;
@Column(name = "amount")
private BigDecimal amount;
@ManyToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "log_type_fk", referencedColumnName = "id")
//@Column(name = "log_type_fk")
private LogType logType;
@ManyToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "fk_network", referencedColumnName = "id")
private Network network;
@ManyToOne
@EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
@JoinColumn(name = "fk_chain", referencedColumnName = "id")
private Chain chain;
}
然后我有一个在我的主要 TransactionStatusLog 实体 class.
上工作的存储库接口public interface TransactionStatusLogRepository extends JpaRepository<TransactionStatusLog, Integer>, JpaSpecificationExecutor {
TransactionStatusLog findById(String id);
List<TransactionStatusLog> findByTransactionLog_Id(Integer transactionId);
List<TransactionStatusLog> findByIsActiveAndTransactionLog_Id(Integer transactionId);
我创建了最后一个方法定义:
List<TransactionStatusLog> findByIsActiveAndTransactionLog_Id(Integer transactionId);
尝试执行以下查询:查找所有 TransactionStatusLog 具有:
- Boolean isActive 字段的值为 true
- 并使 TransactionLog(第二个实体 class)具有特定的 ID 值。
最后我创建了这个 JUnit 测试方法来测试这个存储库查询:
@Test
@Order(3)
@Transactional
public void findByIsActiveAndTransactionLog_IdTest() {
List<TransactionStatusLog> result = this.transactionStatusLogRepository.findByIsActiveAndTransactionLog_Id(37);
assertTrue(result.size() == 1, "The result contains 1 tactive transaction status changes related to the transaction having ID: 37");
}
问题是 运行 这个测试方法(它没有启动,因为我的 Spring Data JPA query by name 方法定义似乎是错误的)我在我的堆栈跟踪中得到这个异常:
Caused by: org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract java.util.List com.easydefi.users.repository.TransactionStatusLogRepository.findByIsActiveAndTransactionLog_Id(java.lang.Integer)! Reason: Failed to create query for method public abstract java.util.List
我的代码有什么问题?我该如何修复它? (如果按名称方法查询对于这样的用例来说太复杂,也可以使用 JPQL)
您能否通过添加“True”并删除下划线来重试。它应该看起来像 ->
List<TransactionStatusLog> result = this.transactionStatusLogRepository.findByIsActiveTrueAndTransactionLogId(37);
List<TransactionStatusLog> findByIsActiveAndTransactionLog_Id(Integer transactionId);
应该接受两个参数。一份用于 isActive
一份用于 transactionLogId
.
正确的形式是:
List<TransactionStatusLog> findByIsActiveAndTransactionLog_Id(boolean isActive, Integer transactionId);
然后调用:
List<TransactionStatusLog> result = transactionStatusLogRepository.findByIsActiveAndTransactionLog_Id(true, 37);