📘 Premium Read: Access my best content on Medium member-only articles — deep dives into Java, Spring Boot, Microservices, backend architecture, interview preparation, career advice, and industry-standard best practices.
🎓 Top 15 Udemy Courses (80-90% Discount): My Udemy Courses - Ramesh Fadatare — All my Udemy courses are real-time and project oriented courses.
▶️ Subscribe to My YouTube Channel (176K+ subscribers): Java Guides on YouTube
▶️ For AI, ChatGPT, Web, Tech, and Generative AI, subscribe to another channel: Ramesh Fadatare on YouTube
1. @Query
Syntax and Usage
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
public interface MyRepository extends CrudRepository<MyEntity, Long> {
@Query("SELECT m FROM MyEntity m WHERE m.propertyName = ?1")
List<MyEntity> findByPropertyName(String propertyName);
}
In this example, MyEntity is your JPA entity, and propertyName is an attribute of MyEntity. The @Query annotation defines a custom query to find entities where propertyName matches a specific value. The ?1 indicates the first parameter of the method that will be used in the query. JPQL vs. Native Queries
@Query(value = "SELECT * FROM my_table WHERE property_name = ?1", nativeQuery = true)
List<MyEntity> findByPropertyNameUsingNativeQuery(String propertyName);
Parameter Binding
@Query("SELECT m FROM MyEntity m WHERE m.propertyName = :propertyName")
List<MyEntity> findByPropertyName(@Param("propertyName") String propertyName);
2. @Procedure
Basic Usage
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.query.Procedure;
import org.springframework.data.repository.query.Param;
public interface UserRepository extends JpaRepository<User, Long> {
@Procedure("user_count")
int getUserCount();
}
In this example, user_count is the name of the database-stored procedure that returns the number of users. The repository method getUserCount is mapped to this stored procedure. Parameter Passing
@Procedure(name = "calculate_bonus")
BigDecimal calculateBonusForUser(@Param("user_id") Long userId);
Here, the stored procedure calculate_bonus expects a user ID as an input parameter and returns a calculated bonus amount. The @Param annotation is used to map the method parameter userId to the stored procedure parameter user_id. Naming Conventions
@Procedure
BigDecimal calculateBonusForUser(@Param("user_id") Long userId);
3. @Lock
import javax.persistence.LockModeType;
import org.springframework.data.jpa.repository.Lock;
import org.springframework.data.repository.CrudRepository;
public interface UserRepository extends CrudRepository<User, Long> {
@Lock(LockModeType.PESSIMISTIC_WRITE)
User findById(Long id);
}
In this case, a pessimistic write lock is applied to the findById method, ensuring that the data is locked for update and preventing concurrent modifications. The available lock modes:
- READ
- WRITE
- OPTIMISTIC
- OPTIMISTIC_FORCE_INCREMENT
- PESSIMISTIC_READ
- PESSIMISTIC_WRITE
- PESSIMISTIC_FORCE_INCREMENT
- NONE
4. @Modifying
Example:
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.transaction.annotation.Transactional;
public interface UserRepository extends CrudRepository<User, Long> {
@Transactional
@Modifying
@Query("UPDATE User u SET u.status = ?1 WHERE u.id = ?2")
int updateUserStatus(String status, Long userId);
}
This example demonstrates updating a user's status, highlighting the need for @Modifying when changing data. 5. @EnableJpaRepositories
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@Configuration
@EnableJpaRepositories(basePackages = "com.example.repositories")
public class JpaConfig {
}
Here, @EnableJpaRepositories tells Spring where to look for JPA repositories, facilitating their automatic implementation based on the defined interfaces. Conclusion
Spring Data JPA's annotation-driven approach significantly reduces the complexity of database operations in Java applications. By understanding these annotations, developers can efficiently manage data access layers, making their code cleaner, more maintainable, and easier to understand.Whether you're executing custom queries, calling stored procedures, managing concurrency, performing write operations, or configuring your JPA repositories, Spring Data JPA's annotations provide the tools you need to succeed.
Comments
Post a Comment
Leave Comment