MergeMitra (α-version) vs Greptile: Automated Code Reviews
Repository
Both tools were evaluated on the same repository ā a realistic, multi-layered backend application.
The project includes:
-
Spring Boot backend architecture
-
Spring Data JPA (Hibernate)
-
Spring Security authentication
-
Repository / Service / Controller layers
-
Admin and user functionality
-
MySQL database
Because the repository contains multiple layers and security configuration, it provided a realistic scenario for testing AI code review tools.
- Spring Boot 2.6
- Spring Data JPA
- Spring Security
- MySQL
- JSP / JSTL
- Spring Boot Actuator
- OpenAPI / Swagger
- Maven
ORIGINAL REPOSITORY:
REFACTORED REPOSITORY:
Head-to-Head Comparison
PR Review Scorecard
After seeing MergeMitra's PR scorecard, I went on to address the issues, raised a PR and found the scores improved on all four dimensions.
Fig 1: MergeMitra PR quality score (Before refactoring)

MergeMitra identified 69 issues. After refactoring the code and resolving these issues, the updated scorecard is shown below.
Fig 2: MergeMitra PR quality score (After refactoring)

Issues highlighted by MergeMitra
Code Correctness & Design Quality
-
HibernateConfiguration.java:69 ā
transactionManager.setSessionFactory(sessionFactory().getObject())may return null during initialization. -
SecurityConfiguration.java:100 ā
UserDetailsServicere-encodes password causing authentication failure. -
SecurityConfiguration.java:96 ā
user.getRole().equals("ROLE_ADMIN")may cause NPE. -
SecurityConfiguration.java:32 ā Deprecated
antMatcher/antMatchersused with new DSL. -
SecurityConfiguration.java:53 ā CSRF protection disabled with form login.
-
cartDao.java:29 ā HQL uses table name (
CART) instead of entity name. -
cartProductDao.java:30 ā Same entity-name issue in HQL.
-
categoryDao.java:32 ā Same entity-name issue in HQL.
-
productDao.java:25 ā Same entity-name issue in HQL.
-
userDao.java:29 ā Same entity-name issue in HQL.
-
cartProductDao.java:41 ā
IN (:product_ids)fails when list is empty. -
cartProductDao.java:36 ā Native query may return DB-specific numeric types (e.g., BigInteger).
-
categoryDao.java:39 ā
session.load()used instead ofsession.get(). -
productDao.java:47 ā Same
session.load()issue. -
categoryDao.java:50 ā Possible NPE in
updateCategory. -
productDao.java:40 ā
Session.update(String.valueOf(Product.class))invalid entity name. -
productDao.java:39 ā
getCurrentSession()used without@Transactional. -
userDao.java:50 ā Logging
user.getPassword(). -
userDao.java:51 ā Plaintext password comparison.
-
userDao.java:56 ā Generic
Exceptioncatch hides real errors. -
userDao.java:73 ā HQL uses
Userinstead ofCUSTOMERentity name. -
CartProductRepository.java:7 ā
JpaRepositoryused without JPA configuration. -
Product.java:24 ā Incorrect
@OneToOnemapping for category (should likely be@ManyToOne). -
productService.java:28 ā
updateProductdoes not verify entity existence. -
userService.java:22 ā Password stored without hashing.
-
UserController.java:95 ā Similar plaintext password handling.
-
userService.java:25 ā Generic
RuntimeExceptionhides real DB error. -
AdminController.java:133 ā
product.setId(categoryId)overwrites product primary key. -
AdminController.java:157 ā Product update endpoint not implemented.
-
AdminController.java:90 ā State-changing operations exposed via GET requests.
-
AdminController.java:231 ā Password updated as plaintext via SQL.
-
UserController.java:127 ā Password exposed in UI model.
Test Quality & Coverage
-
SecurityConfiguration.java:26 ā No tests for security filter chains and access rules.
-
cartDao.java:21 ā DAO queries lack integration tests.
-
cartProductDao.java:34 ā Same DAO query test gap.
-
categoryDao.java:35 ā Same DAO query test gap.
-
productDao.java:23 ā Same DAO query test gap.
-
userDao.java:44 ā No tests for authentication DAO methods.
-
userService.java:22 ā No tests for password hashing logic.
-
cartService.java:16 ā Service methods lack tests.
-
categoryService.java:18 ā Service methods lack tests.
-
productService.java:28 ā Service methods lack tests.
-
AdminController.java:45 ā No controller tests for admin endpoints.
-
UserController.java:42 ā No controller tests for user endpoints.
Code Readability & Maintainability
-
HibernateConfiguration.java:18 ā Non-constant uppercase field names (
DRIVER,URL). -
SecurityConfiguration.java:20 ā Same naming convention issue.
-
HibernateConfiguration.java:44 ā
DriverManagerDataSourceused instead of pooled datasource. -
cartDao.java:13 ā DAO class naming convention violation.
-
cartProductDao.java:14 ā Same naming issue.
-
categoryDao.java:14 ā Same naming issue.
-
productDao.java:15 ā Same naming issue.
-
userDao.java:19 ā Same naming issue.
-
cartService.java:12 ā Service naming convention issue.
-
categoryService.java:14 ā Service naming convention issue.
-
productService.java:12 ā Service naming convention issue.
-
userService.java:14 ā Service naming convention issue.
-
cartDao.java:32 ā Commented-out dead code.
-
userDao.java:40 ā Commented-out dead code.
-
Cart.java:19 ā Commented-out code.
-
cartService.java:20 ā Commented-out code.
-
UserController.java:175 ā Commented-out code.
-
userDao.java:36 ā
System.out.printlnused instead of logging. -
AdminController.java:80 ā Same logging issue.
-
UserController.java:102 ā Same logging issue.
-
AdminController.java:186 ā Controller contains raw JDBC logic.
-
AdminController.java:192 ā Hardcoded DB credentials in controller.
-
AdminController.java:210 ā Password exposed to UI model.
-
AdminController.java:192 ā JDBC resources not closed.
-
UserController.java:96 ā Controller binds HTTP data directly to JPA entity.
Issues highlighted by Greptile
userDao.java ā Wrong HQL entity name (from User instead of from CUSTOMER) causing authentication failure.
AdminController.java (lines 191ā219) ā Hardcoded DB credentials and unclosed JDBC connection.
AdminController.java (lines 233ā236) ā Password stored as plaintext instead of BCrypt hash.
AdminController.java ā product.setId(categoryId) incorrectly sets product ID to category ID.
AdminController.java (lines 157ā163) ā Product update endpoint is a no-op (update call commented out).
UserController.java ā Hashed password exposed to the view (model.addAttribute("password", user.getPassword())).
categoryService.java ā Unused ByteBuddy import.
userDao.java ā Unused MIDI import (Soundbank).
UserController.java (lines 18ā28) ā Duplicate and unused cartService import.
SecurityConfiguration.java ā CSRF protection disabled in both filter chains.
My Experience with MergeMitra
"Using MergeMitra felt like having an expert Java lead reviewing my PR, not a linter checking surface-level issues."
Instead of pointing out syntax-level issues, it identified deeper systemic problems that would have taken hours to find manually.
š Security Vulnerabilities
Detected password logging, double BCrypt encoding, and hardcoded credentials leaking into properties files.
š Architecture Anti-patterns
Controllers were directly performing JDBC operations ā a clear separation-of-concerns violation.
š Transaction Boundaries
Missing @Transactional annotations causing unpredictable DB behavior.
š Entity Relationships
Improper JPA mappings leading to N+1 query problems and data integrity risks.
How It Saved Reviewer Time
Manual code reviews on multi-layer repositories can consume hours. MergeMitra accelerated this process significantly.
Instant critical issue detection
Surfaced incorrect entity mappings, security misconfigs, and transaction issues in one pass ā while the context was still fresh.
Actionable, location-specific suggestions
Each issue included a clear problem description, exact file location, and a suggested code fix.
No ambiguity, no back-and-forth.
Reduced PR review overhead
Catching issues early compressed time spent in pull request reviews, debugging sessions, and security audits.
Final Thoughts
AI-assisted code reviews are becoming an essential part of modern development workflows. While Greptile offers useful lint-style analysis at the line level, my evaluation showed that MergeMitra delivers meaningfully deeper insights ā covering architecture, security, and system design holistically.
For teams building production-grade applications, that level of review can be the difference between shipping reliable software and accumulating silent tech debt.
If you're building with Spring Boot and care about secure, maintainable backend architecture ā both tools are worth exploring. But for depth and architectural context, MergeMitra goes well ahead.