Nomes de método como Query (Spring Data JPA)

Olá.

Estou tentando entender como funcionam as querys a partir de nome com o Spring JPA. Estou usando Hibernate, também.

Por exemplo, dada essa tabela:

Fiz a seguinte implementação do repository:

public interface TokenRepository extends Repository<TokenEntity, String> {

    void save(TokenEntity token);
}

E ela executa bem sua função (salvar algo no banco). Todavia, agora gostaria de fazer uma consulta… mas não entendi muito bem sobre isso.

Como deveria ser a assinatura do método (especialmente seu tipo de retorno), uma vez que eu quero filtrar ainda pelo campo “token_app”?

Já tentei

String findByToken_app(String token_app), mas não entendi se eu deveria passar como parâmetro o token_app. Fora que isso está colidindo diretamente com meu repository, e causando uma UnsatisfiedDependencyException…

Qualquer luz é bem vinda.

[]'s

Até onde consegui entender sobre o funcionamento deste tipo de query do Spring…
Você define o findBy e passa o nome dos parâmetros do objeto pelos quais deseja fazer a busca.
Exemplo:

public class Foo {
    private String bla;
    private Date ble;
    private Integer bli;
}

public Foo findByBlaString qualquerCoisa);
public Foo findByBle(Date DataASerEncontrada);

Coim relação a buscar pelo nome de uma coluna/tabela, aí já não sei dizer.

Oi Darlan.

Bacana, valeu pela contribuição. Tô fazendo da seguinte forma:

@org.springframework.stereotype.Repository
public interface TokenRepository extends Repository<TokenEntity, String> {

    void save(TokenEntity token);

    TokenEntity findByToken_app(String token_app);
}

Mas em tempo de compilação ele falha.

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘authenticationController’ defined in file [/home/fearx/Modelos/IdeaProjects/tools-api/out/production/classes/me/company/toolsapi/controllers/AuthenticationController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘authenticationModel’ defined in file [/home/fearx/Modelos/IdeaProjects/tools-api/out/production/classes/me/company/toolsapi/model/autentication/AuthenticationModel.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘tokenRepository’: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract me.company.toolsapi.entitys.autentication.token.TokenEntity me.company.toolsapi.repository.TokenRepository.findByToken_app(java.lang.String)! No property token found for type TokenEntity!

Estou pesquisando no StackOverflow e também na própria documentação do Spring JPA. Não tá muito claro pra mim ainda essa parte da JPA com Spring e tudo mais. Se houver qualquer material de leitura recomendado, agradeço.

[]'s

Desse jeito que vc tentou fazer, parece que vc quis referenciar o nome do parâmetro (**token_app"), se essa tiver sido sua intenção, em vez disso, vc deve referenciar o atributo da sua entidade (assim como exemplificado pelo @darlan_machado.

@Entity
public class Person {
	private Long id;
	private String firstname;
	private String lastname;

	// getter and setters
}
public interface PessoaRepository extends JpaRepository<Person, Long> {
	
	List<Person> findByLastname(String lastname);
	
	List<Person> findByLastnameIgnoreCase(String lastname);
	
	List<Person> findByLastnameOrderByFirstnameAsc(String lastname);
}

FONTE: JPA Repositories - Query methods

1 curtida

Oi, Lucas.

O que eu quis fazer foi encontrar os registros na tabela token onde o token_app for igual. Um select basico com where.

Minha entity é essa:

@AllArgsConstructor
@NoArgsConstructor
@Entity
@Data
@Table(name = "token")
public class TokenEntity {
    @Id
    @Column(unique = true, nullable = false)
    private String token_app;

    @Column(unique = true, nullable = false)
    private String token_api;

    @Column(unique = true, nullable = false)
    private String token_refresh;

    @Column(nullable = false)
    private LocalDateTime expires;
}

Pensei que passando o token_app como parâmetro (assim como está na minha entity) resolveria meu problema, mas aparentemente não

Agora entendi.
O Spring Data trata o underscore (_) como um identificador a parte.
Ou seja, ele entende que você tem uma propriedade chamada “token” e que esse cara é um objeto. E, a partir disso, você quer pegar algo nele que se chama “app”.

Uma opção para solucionar

Pela documentação, parece que o _ é um caracter reservado.

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-property-expressions

Fantástico!

Não fazia ideia desse lance do underscore. O lance é evitar usar ele, aparentemente.

Me parece que o Hibernate transcreve o camel case na hora de criar as tabelas. Dei drop na table e vi que ela subiu com underscore, mesmo eu tendo trocado o nome dos atributos.

Me corrijam se estiver errado, claro. E obrigado pela ajuda!

[]'s

No mapeamento das classes, o ideal é usar a convenção do java, deixa os _ para as colunas do banco somente (como orientado pelo @darlan_machado).

Complementando: algumas vezes, quando mapeamos de um xsd para um pojo, o mecanismo do XJC (ou outra ferramenta que o faça) acaba gerando atributos com os famigerados _.
Neste caso, a solução é seguir o que uma das respostas do link que sugeri orienta:

@Query("select s from Student s where s.s_name=?")
List<Student> findBySName();

E definir a query “na unha”.

ja esta resolvido mas… o que eu poderia dizer eh que esse find ai poderia ser resolvido pelo mapeamento da jpa.

@Entity
public class Token {
    @column(name = "token_app")
    private String tokenApp;
}



@Repository
public interface TokenRepository ... {
    findByTokenApp(String tokenApp);
}

assim nao precisa usar o _ e os metodos funcionam normalmente para mim

1 curtida