【问题标题】:Spring CrudRepository findBy* method returning no resultsSpring CrudRepository findBy* 方法没有返回结果
【发布时间】:2018-06-02 16:51:54
【问题描述】:

我已经实现了一个扩展 CrudRepository 的存储库。底层模型(Account)有一个plaidAccountId字段,对应的查询方法是findByPlaidAccountId。最好我能说的是,当其他模型上的其他查询正常工作时,我已经正确连接了它。但是,此查询不返回任何结果。我已经手动验证了数据库中存在与提供的查询参数匹配的项目,但仍然返回 null。

以下是相关配置。让我知道是否还有其他有用的信息可以发布。提前致谢。

我正在执行的查询:

accountService.findByPlaidAccountId(account.getAccountId()

我已登录以验证 accountService 已初始化并且 account.getAccount() 提供了预期的字符串值。

// AccountRepository.java
@Repository
public interface AccountRepository extends CrudRepository<Account, Long> {

    Set<Account> findAllByUser(User user);
    Account findByPlaidAccountId(String plaidAccountId);
    Account findById(int id);
    Account findAccountByPlaidAccountId(String plaidAccountId);
}

--

// AccountService.java
@Service
public class AccountService {

    private AccountRepository accountRepository;

    @Autowired
    public AccountService(AccountRepository repository) {
        this.accountRepository = repository;
    }

    public Account findById(int id) {
        return accountRepository.findById(id);
    }

    public Account findByPlaidAccountId(String plaidAccountId) {
        return accountRepository.findByPlaidAccountId(plaidAccountId);
    }

    public Iterable<Account> findAll() {
        return accountRepository.findAll();
    }

    public Set<Account> findAllByUser(User user) {
        return accountRepository.findAllByUser(user);
    }

    public void saveAccount(Account account) {
        accountRepository.save(account);
    }

    public Account findAccountByPlaidAccountId(String plaidAccountId) {
        return accountRepository.findAccountByPlaidAccountId(plaidAccountId);
    }
}

--

// Account.java
@Entity
@Table(name = "accounts")
public class Account {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "account_id")
private int id;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "user_id", nullable = false)
private User user;

@Column(name = "plaid_account_id")
@NotEmpty(message = "Plaid account number is required")
private String plaidAccountId;

@Column(name = "account_type")
private String accountType;

@Column(name = "account_subtype")
private String accountSubtype;

@Column(name = "institution_id")
private String institutionId;

@Column(name = "current_balance")
private double currentBalance;

@Column(name = "available_balance")
private double availableBalance;

@Column(name = "account_limit")
private double accountLimit;

@Column(name = "name")
private String name;

@Column(name = "official_name")
private String officialName;

@Column(name = "mask")
private String mask;

@ManyToOne
@JoinColumn(name = "plaid_item_id", nullable = false)
private PlaidItem plaidItem;

public Account() {
}
// ... getters and setters

更新:JPA SQL 日志记录

Hibernate: select account0_.account_id as account_1_0_, account0_.account_limit as account_2_0_, account0_.account_subtype as account_3_0_, account0_.account_type as account_4_0_, account0_.available_balance as availabl5_0_, account0_.current_balance as current_6_0_, account0_.institution_id as institut7_0_, account0_.mask as mask8_0_, account0_.name as name9_0_, account0_.official_name as officia10_0_, account0_.plaid_account_id as plaid_a11_0_, account0_.plaid_item_id as plaid_i12_0_, account0_.user_id as user_id13_0_ from accounts account0_ where account0_.plaid_account_id=?

【问题讨论】:

标签: spring hibernate spring-boot spring-data spring-data-jpa


【解决方案1】:

我在你的代码中看到了一些可能会产生未来问题的东西,我不知道它们是否会给你带来麻烦,但将来会给你带来麻烦。

// AccountRepository.java 
 @Repository 
 public interface AccountRepository extends CrudRepository<Account, Long> {        
    Set<Account> findAllByUser(User user);        
    Account findByPlaidAccountId(String plaidAccountId);      
    Account findById(int id);        
    Account findByPlaidAccountId(String plaidAccountId); 
 }

第一件事是“CrudRepository&lt;Account, Long&gt;”你这里有Long但是你的类的ID是“int”,它们应该是一样的。

Account findByPlaidAccountId(String plaidAccountId);
Account findAccountByPlaidAccountId(String plaidAccountId);

这两个方法期望返回单个 Account 对象,但 plaidAccountId 不是唯一的或 pk,因此您必须期望一个列表。 如果您确定只有一个元素并且没有一个元素可以处理您的应用程序中的列表,只需将存储库更改为 Set/List&lt;Account&gt; 并且服务保持如下:

public Account findByPlaidAccountId(String plaidAccountId) {
        return accountRepository.findByPlaidAccountId(plaidAccountId).get(0);
}

findFirstByPlaidAccountId

祝你好运,返回 null ;)。

【讨论】:

  • 我不能接受这个答案,因为它不能解决问题中的问题,但我非常感谢这些提示!当我学习框架时,这些东西对理解非常有帮助。关于 CrudRepository 扩展中 ID 值的问题:我在模型中使用原始 int 值,但存储库实例化不会采用原始​​值。如果我在那里传递Integer,它的行为会一样吗?
【解决方案2】:

由于某种原因,我的值已保存到数据库中包括它们的引号,所以正确的查询在技术上是"&lt;value&gt;"

【讨论】:

    【解决方案3】:

    如果您通过 plaidAccountId 搜索(您的方法是如何调用的)我想您想传递该 id 而不是 account.getAccountId()

    accountService.findByPlaidAccountId(...)
    

    【讨论】:

    • 感谢您的建议,但这只是域模型之间的差异。在外部,从 API 中,目标值返回为 accountId。因为我的应用程序中有内部帐户 ID,所以我添加了命名空间 plaid,因此 accountIdexternal 值映射到 plaidAccountIdinternal 值.这两个值被映射到每个,所以getAccountId()的结果是正确的值传入。
    猜你喜欢
    • 2020-02-12
    • 2018-01-07
    • 2018-01-07
    • 2019-03-07
    • 2019-01-13
    • 1970-01-01
    • 2023-03-15
    • 2018-06-10
    相关资源
    最近更新 更多