@Entity @Table(name = "PERSONS") @NamedNativeQueries({ @NamedNativeQuery( name = "getPersonBasic", query = "SELECT p.name, p.surname FROM persons where p.surname = ?", resultClass = Person.class), @NamedNativeQuery( name = "getPersonDetails", query = "SELECT p.name, p.surname, p.age, p.street, p.city FROM persons where p.surname = ?", resultClass = Person.class) }) public class Person { private String name; @Id private String surname; private int age; private String street; private String city; }
Now, in my application I am getting Person with surname "Stawicki" without details, by "getPersonBasic" query. Then I need detailed person in the same transaction, so I execute "getPersonDetails". And... I am getting Person without age, street and city. This three fields are null. Why? Do you already know? If not, look below for answer.
The problem is in cache, and in @Id which is only on surname field. First person is retrieved without details and stored in cache. Then we try to get person with details, but JPA doesn't understand difference between our queries. It queries the database, and identifies that if it builds entity from resulting ResultSet, it is going to have the same @Id as entity which is already in cache. If @Id is the same, logically it is the same entity. So it just returns it without building whole entity from ResultSet.