[JIRA] (HHH-16936) Entity not being removed from persistence context after a delete in JPQL
by Jean-Baptiste Hainaut (JIRA)
Jean-Baptiste Hainaut ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=712020%... ) *updated* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiZDY1ODA2MWJj... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-16936?atlOrigin=eyJpIjoiZDY1OD... ) HHH-16936 ( https://hibernate.atlassian.net/browse/HHH-16936?atlOrigin=eyJpIjoiZDY1OD... ) Entity not being removed from persistence context after a delete in JPQL ( https://hibernate.atlassian.net/browse/HHH-16936?atlOrigin=eyJpIjoiZDY1OD... )
Change By: Jean-Baptiste Hainaut ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=712020%... )
When using a composite id, the entity is not removed from the persistance context with a delete query written in JPQL
Our Entity and composite id :
{code:java}@Entity
@NoArgsConstructor(access = AccessLevel.PRIVATE, force = true)
public class SchoolSetting {
@EmbeddedId
private final SchoolSettingId id;
@Getter
private boolean activated;
public SchoolSetting(@NonNull final String schoolId,
@NonNull final String key,
final boolean activated) {
this.id = new SchoolSettingId(schoolId, key);
this.activated = activated;
}
public String getKey() {
return this.id.getKey();
}
}
@Embeddable
@NoArgsConstructor(access = AccessLevel.PRIVATE, force = true)
@Getter(AccessLevel.PROTECTED)
@EqualsAndHashCode
public class SchoolSettingId implements Serializable {
private final String schoolId;
private final String key;
public SchoolSettingId(@NonNull final String schoolId,
@NonNull final String key) {
this.schoolId = schoolId;
this.key = key;
}
}{code}
The repository :
{code:java}interface SpringDataSchoolSettingRepository extends CrudRepository<SchoolSetting, SchoolSettingId> {
@Query("delete from SchoolSetting s WHERE s.id.key = :id")
@Modifying
void deleteById(@Param("id") SchoolSettingId id);
}{code}
The following test fail without the testEntityManager.clear() as the entity is still in the persistence context. We we are able to reproduce the same behavior with production code inside the same transaction
{code:java}@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Import(JpaSchoolSettingRepository.class)
class JpaSchoolSettingRepositoryIT {
static String SCHOOL_ID = "MY_SCHOOL";
@Autowired
TestEntityManager testEntityManager;
@Autowired
JpaSchoolSettingRepository jpaSchoolSettingRepository;
@Test
void deleteTwiceShouldntThrowAnyException() {
testEntityManager.persistAndFlush(createSetting());
assertThat(jpaSchoolSettingRepository.get(new SchoolSettingId(SCHOOL_ID, "ABSENCE_FOR_DAY_OFF")))
.isNotEmpty();
jpaSchoolSettingRepository.delete(new SchoolSettingId(SCHOOL_ID, "ABSENCE_FOR_DAY_OFF"));
//testEntityManager.clear();
assertThat(jpaSchoolSettingRepository.get(new SchoolSettingId(SCHOOL_ID, "ABSENCE_FOR_DAY_OFF")))
.isEmpty();
assertThatCode(() -> jpaSchoolSettingRepository.delete(new SchoolSettingId(SCHOOL_ID, "ABSENCE_FOR_DAY_OFF")))
.doesNotThrowAnyException();
}
private SchoolSetting createSetting() {
return new SchoolSetting(SCHOOL_ID, ABSENCE_FOR_DAY_OFF, true);
}
}{code}
If we change the query to the following, it work as expected :
{code:java}@Query("delete from SchoolSetting s WHERE s.id.key = :schoolId and s.id.schoolId = :key")
@Modifying
void deleteById(String schoolId, String key);{code}
So we conclude that the bug is related with the handling of the composite key
( https://hibernate.atlassian.net/browse/HHH-16936#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-16936#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100232- sha1:33a7c72 )
2 years, 8 months