spring-projects / spring-data-commons

Spring Data Commons. Interfaces and code shared between the various datastore specific implementations.
https://spring.io/projects/spring-data
Apache License 2.0
782 stars 675 forks source link

Incorrect implementation of "ID" in SQL queries #3173

Closed olech2412 closed 1 month ago

olech2412 commented 1 month ago

We have the following behavior.

There is a class that is structured like this:

@Entity
@Table(name = "my_entity")
public class MyEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long pk;

    private Long id;
    private String name;

    public MyEntity() {
    }
}

The corresponding repository looks like this and contains a function "existsById":

@Repository
public interface MyEntityRepository extends CrudRepository<MyEntity, Long> {

    boolean existsById(Long id);

    boolean existsByIdAndName(Long id, String name);
}

Suppose the database contains the following data record:

pk🔑 id name
1 204 Name1
2 2830 Name2
3 52235 Name3

In our case the following behavior occurred:

existsById(204L) -> false

existsById(2L) -> true

existsByIdAndName(204L, "Name1") -> true

The behavior that was expected was:

The identifier Id in the function name "existsById" refers exclusively to the attribute of the class and is not internally reserved for the primary key. Accordingly, every query should only target this attribute without exception.

SpringBoot-Starter-Data-JPA-Version: 3.3.3

christophstrobl commented 1 month ago

Thank you @olech2412 for getting in touch. This is a topic that has been discussed when working on the naming proposed via #1399 and in particular this comment.

Looking at the reference documentation I do see a need to be more clear about predefined method names and strategies to cope with the described scenario. I might be wrong, but it seems only the Repository Core Concepts briefly touches upon this topic in one of the snippets.

olech2412 commented 1 month ago

Hi @christophstrobl , thanks for the answer. I also think it would make sense if this were better documented. We then thought about what was happening, but we couldn't estimate whether this was a bug or at what level in the data layer the cause lay. The conflict probably doesn't occur very often, but in the situations where it does happen it is probably even more serious. Thank you for your effort! 🚀