1

I am working on a desktop application built using spring framework and one of the part of the application is not working. I found that the repository class does not have any queries with @Query annotation. I haven't encountered it before.

When I try to open the form that uses this, I get an error that the application is not able to connect to the database. The application has 3 databases specified in the application.properties. I have the following questions:

1) How does the following code work without a query specified with @Query annotation. Or where is the query written.

@Repository
public interface AccountRepository extends JpaRepository<Account, Long> {

    List<Account> findAccountsByActiveIsTrueAndAccountTypeEquals(String accountType);

    List<Account> findAccountsByAccountTypeLike(String type);
}

2) How do we specify which of the database to search for. For example: I have 3 mysql databases currently connected to my application. I wish to access data from DB1 through my Spring boot application through the usual flow of UI model-> BE Controller/ Service layer -> Repository(Interface) which (usually) has the query written with @Query. How we specify which database this query goes for ?

Romil Patel
  • 12,879
  • 7
  • 47
  • 76
Nitin Nanda
  • 805
  • 2
  • 11
  • 27

3 Answers3

2

For your first question I can answer that the JpaRepository has an internal system that analyses the method name you have written and then generates the query that has to be executed to the database.

The @Query annotation is used when the method name and the generated query is not returning the result you wanted to so you specifically tell the compiler which query should be executed.

As mentioned here: https://docs.spring.io/spring-data/jpa/docs/1.5.0.RELEASE/reference/html/jpa.repositories.html

2.3.1 Query lookup strategies. The JPA module supports defining a query manually as String or have it being derived from the method name. Declared queries Although getting a query derived from the method name is quite convenient, one might face the situation in which either the method name parser does not support the keyword one wants to use or the method name would get unnecessarily ugly. So you can either use JPA named queries through a naming convention (see Section 2.3.3, “Using JPA NamedQueries” for more information) or rather annotate your query method with @Query (see Section 2.3.4, “Using @Query” for details).

So basically using a naming convention will do the magic.

Also an interesting question and perfect answer can be found here: How are Spring Data repositories actually implemented?

For your second question you can refer to this example:

https://www.baeldung.com/spring-data-jpa-multiple-databases

It might be a bit complicated in the beginning but eventually it will work.

Painful
  • 137
  • 1
  • 11
1

He use JPA, JpaRepository has CRUD methodes

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#reference

In your application.properties, you can put your mysql DB info

Yiao SUN
  • 908
  • 1
  • 8
  • 26
1

Why this works without @Query?

Because you are using JpaRepository which provides an easy way to get data based on your entity and it's fields.

Here your Account will have active, accountType etc fields. You can use JPA's query creation keywords such as AND, OR, Equals, Like and many more.

Derived queries with the predicates IsStartingWith, StartingWith, StartsWith, IsEndingWith", EndingWith, EndsWith, IsNotContaining, NotContaining, NotContains, IsContaining, Containing, Contains the respective arguments for these queries will get sanitized. This means if the arguments actually contain characters recognized by LIKE as wildcards these will get escaped so they match only as literals. The escape character used can be configured by setting the escapeCharacter of the @EnableJpaRepositories annotation.


How do we specify which of the database to search? You can create configuration classes based on your databases and define data sources based on that using @PropertySource.

For more details see example here

@Configuration
@PropertySource({ "classpath:persistence-multiple-db.properties" })
@EnableJpaRepositories(
    basePackages = "com.baeldung.multipledb.dao.product", 
    entityManagerFactoryRef = "productEntityManager", 
    transactionManagerRef = "productTransactionManager"
)
Romil Patel
  • 12,879
  • 7
  • 47
  • 76