【问题标题】:java.lang.IllegalArgumentException: Failed to create query method in a JpaRepositoryjava.lang.IllegalArgumentException:无法在 JpaRepository 中创建查询方法
【发布时间】:2018-12-09 10:30:08
【问题描述】:

我使用技术 jpa、hibernate、spring boot - data、api REST。

我有以下错误:

org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为“walletRestService”的bean时出错:通过字段“walletRepository”表示的依赖关系不满足;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“walletRepository”的 bean 时出错:调用 init 方法失败;嵌套异常是 java.lang.IllegalArgumentException: 无法创建查询方法 public abstract java.lang.Long com.wj.dao.WalletRepository.createWallet(java.lang.Long,java.lang.String)!没有找到类型 Wallet 的属性 createWallet!

这是我的代码:

实体用户:

package com.wj.entities;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;

import com.fasterxml.jackson.annotation.JsonManagedReference;

@Entity
public class User implements Serializable{

@Id
@GeneratedValue
private Long id; 
private String name;

@OneToMany(mappedBy="user", fetch=FetchType.LAZY)
@JsonManagedReference
private List<Wallet> wallets = new ArrayList<>();

public User() {
    super();
}

public User(String name) {
    super();
    this.name = name;
}



public User(Long id, String name) {
    super();
    this.id = id;
    this.name = name;
}



public User(Long id, String name, List<Wallet> wallets) {
    super();
    this.id = id;
    this.name = name;
    this.wallets = wallets;
}

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public List<Wallet> getWallets() {
    return wallets;
}

public void setWallets(List<Wallet> wallets) {
    this.wallets = wallets;
}


}

实体钱包:

@Id
@GeneratedValue
private Long id;
private String name;
@ManyToOne
@JoinColumn(name="user_id")
@JsonBackReference    
private User user;

public Wallet() {
    super();
}




public Wallet(String name, User user) {
    super();
    this.name = name;
    this.user = user;
}




public Wallet(Long id, String name, User user) {
    super();
    this.id = id;
    this.name = name;
    this.user = user;
}



public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public User getUser() {
    return user;
}

public void setUser(User user) {
    this.user = user;
}


}

restApi:

@RequestMapping(value="/wallets", method=RequestMethod.POST)
public Wallet save(@RequestBody Wallet wallet) {
    User user = wallet.getUser();

    Long id = walletRepository.createWallet(user.getId(), wallet.getName());
    User boundUser = wallet.getUser();
    User simpleUser = new User(boundUser.getId(), boundUser.getName());
    wallet = new Wallet(id, wallet.getName(), simpleUser);
    return walletRepository.save(wallet);
}

DAO:  

package com.wj.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import com.wj.entities.Wallet;

public interface WalletRepository extends JpaRepository<Wallet, Long>{
   Long createWallet(Long id, String name);
}

【问题讨论】:

  • 显示您的 WalletRepository 实现。

标签: hibernate jpa spring-data-jpa


【解决方案1】:

WalletRepository 接口中的此声明对 Spring 无效:

Long createWallet(Long id, String name);

您希望 Spring 如何猜测 createWallet() 方法旨在创建和持久化具有 Long idString nameWallet 实体?

事实上,您在WalletRepository 接口中声明的方法是检索方法,它们依赖于命名约定以允许 Spring 为您创建查询。并且 create 在 Spring Data 文档中没有被引用:

4.4.2. Query Creation

该机制去除前缀find…Byread…Byquery…By、 来自方法的count…Byget…By 并开始解析其余的 它。

由于 Spring 无法识别 create,它可能会尝试将 createWallet 解析为实体的字段。而消息:

找不到类型 Wallet 的属性 createWallet!

要保存实体,请改用JpaRepository 中提供的方法:

<S extends T> S save(S entity);

您的存储库将被推断为:

Wallet save(Wallet entity);

调整您的客户端代码以创建Wallet 实例并将其传递给save()

如:

@RequestMapping(value="/wallets", method=RequestMethod.POST)
public Wallet save(@RequestBody Wallet wallet) {
    User boundUser = wallet.getUser();
    return walletRepository.save(wallet);
}

【讨论】:

  • 我不太明白你的回答。你能给我一个我的代码的例子吗?谢谢
  • 试图按照你告诉我的去做,他向我显示了以下错误:org.springframework.beans.factory.BeanCreationException:创建类路径资源中定义的名称为“entityManagerFactory”的bean时出错[org/springframework /boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]:init 方法调用失败;嵌套异常是 org.hibernate.AnnotationException:Collection 既没有泛型类型也没有定义 OneToMany.targetEntity():com.wj.entities.User.wallets
  • 你不需要声明方法。 JpaRepository 中已经提供了它。但是 createWallet() 方法的目标是什么?
  • 它允许我创建一个钱包,知道一个钱包有一个用户和名称。当我在 restService 中调用 createWallet () 时,它会强制我在 DAO 中创建它。否则我必须在 restService 中调用什么函数,以避免出错,知道要创建钱包我需要设置 user.id 和名称?
猜你喜欢
  • 1970-01-01
  • 2021-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-12
  • 2019-03-08
相关资源
最近更新 更多