-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
All my @DataJpaTest tests fail when I try to insert / update a @Entity when the @Entity has a Boolean property annotated with a @Converter (like org.hibernate.type.YesNoConverter, but also with a similar Converter implemented by us)
- Affected environments: Spring Boot
4.0.2and4.1.0-M1 - Works correctly on Spring Boot
3.5.10 - Demo Project (created with the spring initializr) to reproduce the issue: https://github.com/xtermi2/data-jpa-test-with-boolean-converter-issue
- Inserting
nullvalues works as expected
The JPA Entity
@Entity
public class MyEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
Long id;
@Version
private Integer version;
@Convert(converter = YesNoConverter.class)
private Boolean paused;
@Column(length = 120)
private String name;
...The Test
@DataJpaTest(showSql = true, properties = {
"spring.jpa.show-sql=true",
"spring.jpa.properties.hibernate.format_sql=true",
"logging.level.org.hibernate.SQL=DEBUG",
"logging.level.org.hibernate.orm.jdbc.bind=TRACE",
})
class MyEntityRepositoryTest {
@Autowired
private MyEntityRepository repository;
@Autowired
private EntityManager entityManager;
@Test
void testWithConverter() {
MyEntity entity = new MyEntity();
entity.setName("Test Entity");
entity.setPaused(true);
MyEntity savedEntity = repository.save(entity);
flushAndClear();
assertThat(savedEntity.getPaused())
.isTrue();
savedEntity.setPaused(null);
repository.save(savedEntity);
flushAndClear();
MyEntity fetchedEntity = repository.findById(savedEntity.getId()).orElseThrow();
assertThat(fetchedEntity.getPaused())
.isNull();
}
private void flushAndClear() {
entityManager.flush();
entityManager.clear();
}
}Failure Message:
Ungültige Bedingung: "CONSTRAINT_D: "
Check constraint invalid: "CONSTRAINT_D: "; SQL statement:
insert into my_entity (name,paused,version,id) values (?,?,?,?) [23514-240]
could not execute statement [Ungültige Bedingung: "CONSTRAINT_D: "
Check constraint invalid: "CONSTRAINT_D: "; SQL statement:
insert into my_entity (name,paused,version,id) values (?,?,?,?) [23514-240]] [insert into my_entity (name,paused,version,id) values (?,?,?,?)]
org.hibernate.exception.ConstraintViolationException: could not execute statement [Ungültige Bedingung: "CONSTRAINT_D: "
Check constraint invalid: "CONSTRAINT_D: "; SQL statement:
insert into my_entity (name,paused,version,id) values (?,?,?,?) [23514-240]] [insert into my_entity (name,paused,version,id) values (?,?,?,?)]
The error occured when the flush forces JPA to execute the insert in the in-memory H2 DB.
I enabled logging an can see, that the table was created correctly and the query with the parameters looking OK:
create table my_entity (
paused char(1) check ((paused in ('N','Y'))),
version integer,
id bigint not null,
name varchar(120),
primary key (id)
)
insert
into
my_entity
(name, paused, version, id)
values
(?, ?, ?, ?)
2026-01-29T11:27:29.819+01:00 TRACE 240391 --- [data-jpa-test-with-boolean-converter] [ Test worker] org.hibernate.orm.jdbc.bind : binding parameter (1:VARCHAR) <- [Test Entity]
2026-01-29T11:27:29.819+01:00 TRACE 240391 --- [data-jpa-test-with-boolean-converter] [ Test worker] org.hibernate.orm.jdbc.bind : binding parameter (2:CHAR) <- [Y]
2026-01-29T11:27:29.819+01:00 TRACE 240391 --- [data-jpa-test-with-boolean-converter] [ Test worker] org.hibernate.orm.jdbc.bind : binding parameter (3:INTEGER) <- [0]
2026-01-29T11:27:29.819+01:00 TRACE 240391 --- [data-jpa-test-with-boolean-converter] [ Test worker] org.hibernate.orm.jdbc.bind : binding parameter (4:BIGINT) <- [1]
2026-01-29T11:27:29.822+01:00 WARN 240391 --- [data-jpa-test-with-boolean-converter] [ Test worker] org.hibernate.orm.jdbc.error : HHH000247: ErrorCode: 23514, SQLState: 23514
2026-01-29T11:27:29.822+01:00 WARN 240391 --- [data-jpa-test-with-boolean-converter] [ Test worker] org.hibernate.orm.jdbc.error : Ungültige Bedingung: "CONSTRAINT_D: "
The only difference I saw that in Spring Boot 3.5 the create table statement for the affected field was paused char(1) check (paused in ('N','Y')), and with Spring Boot 4 paused char(1) check ((paused in ('N','Y'))), <- So spring Boot 4 is generating unnecessary braces.
== Workarounds
Adding @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) to each @DataJpaTest annotated test resolves the issue:
- the logs show the same create table statement
- the logs show the same insert statement with the same parameters