【问题标题】:@Autowired JPA Repository in spring boot春季启动中的@Autowired JPA 存储库
【发布时间】:2018-03-22 13:43:26
【问题描述】:

当我尝试构建项目时,@Autowired 和我的 JpaRepository 类出现问题,问题出现在这里。

这是我的 Jpa Repository 类。

public interface IJpaRepositoryLivrariaDAO extends JpaRepository<EntidadeDominio, Long> {
    List<Cliente> findByCliente(Cliente cliente); // whem I put this line of code I've get the exeption below                                           
}

DAO 实现

@Repository
public class ClienteDAO implements IDAO {

    @Autowired
    List<Cliente> cliente;

    @Autowired
    IJpaRepositoryLivrariaDAO jpaRepositoryLivraria;

    
    @Override
    public void consultar(ModelMap modelMap) {

        Cliente c = (Cliente) modelMap.get("object");

        modelMap.addAttribute("object", jpaRepositoryLivraria
            .findByCliente(c));

}

例外

2017-10-10 21:18:58.524 WARN 4000 --- [restartedMain] ationConfigEmbeddedWebApplicationContext:上下文初始化期间遇到异常 - 取消刷新尝试:

org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为“alterarCommand”的bean时出错:通过字段“fachada”表达的依赖关系不满足;

嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“fachada”的 bean 时出错:资源依赖注入失败;

嵌套异常是 org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为 'clienteDAO' 的 bean 时出错:通过字段 'jpaRepositoryLivraria' 表达的依赖关系不满足;

嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“IJpaRepositoryLivrariaDAO”的 bean 时出错:调用 init 方法失败;

嵌套异常是 org.springframework.data.mapping.PropertyReferenceException: No property cliente found for type Cliente!

如果我错了,请纠正我,问题是我的客户列表中没有客户或类似的东西

列出 findByCliente(Cliente cliente);

提前感谢您的帮助。

更新 1。

好的,根据答案,我做了一些更改,试图使代码正常工作。

首先,如果我在 EntidadeDominio 中放置一个 Cliente 属性,它会弄乱我的数据库,所以我创建了一个新的 JPARepository,试图让代码更易于理解和执行

public interface IJpaRepositoryClienteDAO extends JpaRepository<Cliente, Long> {
            
    // I don't know the best way to use @Query, what I'm trying to do here
    // is to select * from Cliente where any of the clients 
    // atributes matches with their corresponding columns
            
    @Query("select c from Cliente c where c like %?1")
    List<Cliente> findByCliente(Cliente cliente);
            
}

然后在

中调用这个方法
public class ClienteDAO 
    
    @Autowired
    IJpaRepositoryClienteDAO jpaRepositoryCliente;

    public void consultar(ModelMap modelMap) {

        Cliente c = (Cliente) modelMap.get("object");

        modelMap.remove("object");
        modelMap.remove("cliente");
    
        modelMap.addAttribute("object", jpaRepositoryLivraria.findByCliente(c));
    }
}

这是我的 Cliente 类和他的绑定类,以便更好地理解

@Entity
@Component
@DiscriminatorValue("Cliente")
public class Cliente extends EntidadeDominio {

    @Embedded
    private Genero genero;
    private boolean ativo;

    @OneToMany(mappedBy = "cliente", targetEntity = CartaoCredito.class, cascade = CascadeType.ALL, orphanRemoval = true)
    private List<CartaoCredito> cartaoCredito = new ArrayList<>();

    @OneToMany(mappedBy = "cliente", targetEntity = Endereco.class, cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Endereco> endereco = new ArrayList<>();
}

@Entity
@Component
public class CartaoCredito {

    @Id
    @GeneratedValue( strategy=GenerationType.AUTO )
    private long id_cartao_credito;
    private String numero;
    private String nomeCartao;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_cliente")
    private Cliente cliente;
}

@Entity
@Component
public class Endereco {
    
    @Id
    @GeneratedValue
    private Long id_endereco;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_cliente")
    private Cliente cliente;
}

这样做会改变代码的工作原理,现在的问题是我收到了这个错误

java.lang.IllegalArgumentException:参数值 [%com.les.livraria.dominio.cliente.Cliente@1a1147e] 与预期类型不匹配 [com.les.livraria.dominio.cliente.Cliente (n/a)]

对象在我的 ClienteDAO 类中被正确发送

modelMap.addAttribute("object", jpaRepositoryLivraria.findByCliente(c));

好吧,现在我要跟踪这个错误,看看是什么问题的根源,如果有人对如何处理这个问题有任何想法,我将非常感激,现在非常感谢。

【问题讨论】:

  • 添加EntidadeDominio的代码。

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


【解决方案1】:

感谢@Zeromus,我认为可以从我的 pojo 类生成,现在很明显这是不可能的,我正在使用反射来进行通用查询,该方法仍然不完整,它需要异常治疗。我不知道这是否是解决此问题的最佳解决方案,但我将其发布在这里,也许它可以帮助某人。

public class ReflectionQueryCreator {

    private String sql = "";
    private String nomeAtributo;
    private Object metodoValor;

    public String queryBuilderCliente(Cliente object, Class<Cliente> classe) {

        Method[] classMethods = classe.getMethods(); 
        Field[] classFields = classe.getDeclaredFields();

        for (Method method : classMethods) {
            try {
                if (method.getName().substring(0, 3).equals("get")) {

                    metodoValor = method.invoke(object);

                    for (Field field : classFields) {
                        nomeAtributo = field.getName();

                        if (method.getName().toLowerCase().endsWith(nomeAtributo.toLowerCase()))

                            if (!(metodoValor.equals("") || metodoValor.equals(0) || method.toString().contains("Id"))) {

                                if (method.getReturnType().getSimpleName().equals("String"))
                                    sql = sql + object.getClass().getSimpleName().toLowerCase() + "." + nomeAtributo + " like %" + metodoValor + "% and ";

                                else if (method.getReturnType().getSimpleName().equals("long") && metodoValor.equals(0))
                                    sql = sql + object.getClass().getSimpleName().toLowerCase() + "." + nomeAtributo + " = " + metodoValor + " and ";

                            } else
                                break;
                    }
                }
            } catch (IllegalAccessException ex) {ex.printStackTrace();}
              catch (IllegalArgumentException ex) {ex.printStackTrace();} 
              catch (InvocationTargetException ex) {ex.printStackTrace();}
        }
        return sql;
    }

【讨论】:

    【解决方案2】:

    IJpaRepositoryLivrariaDAO 正在管理您的 EntidadeDominio 实体的持久性。

    像这样更新你的存储库

    public interface IJpaRepositoryLivrariaDAO extends JpaRepository<EntidadeDominio, Long> {
    
        List<EntidadeDominio> findByCliente(Cliente cliente); // This will return a list of EntidadeDominio
    
    }
    

    以后你可以这样做

    List<EntidadeDominio> entidadeDominios =  repository.findByC...;
    List<Cliente> clients = entidadeDominios.getCliente(); //Given that you have Cliente as composition in your EntidadeDominio entity.
    

    【讨论】:

      【解决方案3】:

      我认为在您的 EntidadeDominio 类中,您需要一个 Cliente 字段类型,然后您可以使用 findByCliente

      class EntidadeDominio  {
      
      private Cliente  cliente  ;
      
      // getter && setter 
      
      }
      

      并且在你的 dao findByCliente 中应该返回 EntidadeDominio List&lt;EntidadeDominio&gt; 的列表而不是客户列表

      public interface IJpaRepositoryLivrariaDAO extends 
      
          JpaRepository<EntidadeDominio, Long> {
              List<EntidadeDominio> findByCliente(Cliente cliente);  
          }
      

      【讨论】:

        【解决方案4】:

        那里有一些错误...

        1- 异常告诉您 spring 找不到客户字段/属性,特别是:findByCliente(Cliente cliente) 表示您需要在 EntidadeDominio 类中指定的字段 Cliente cliente 被扩展 JpaRepository .

        2- 此外,由于JpaRepository 属于EntidadeDominio,我希望findByCliente 返回类型应该是List&lt;EntidadeDominio&gt;

        我不确定你的目标是什么

        【讨论】:

        • @Zeromous 我用List&lt;EntidadeDominio&gt; 进行了测试,但仍然遇到同样的问题,但是更改了JpaRepository&lt;EntidadeDominio, Long&gt; 代码编译,我想如果我在我的类@987654332 中放置一个Cliente 类型的属性@ 就像@ErrabiAyoub 和@AbdullahKhan 提到的那样,它将使它工作,但正如我所说,这会弄乱我的数据库,关于你的问题,我基本上是试图用对象而不是参数进行查询,因为我有一个他们中的很多人可以进行我需要的查询。
        • @Wesley Silva 好的,您的更新现在正在解释您要做什么。但是 afaik 你不能像这样传递一个完整的实体并期望它为每个相应的实体字段魔术化所有 where 语句......
        猜你喜欢
        • 1970-01-01
        • 2023-01-25
        • 2020-05-17
        • 1970-01-01
        • 2020-08-19
        • 1970-01-01
        • 2015-04-18
        • 1970-01-01
        • 2016-11-12
        相关资源
        最近更新 更多