My Spring Boot application uses Spring Data JPA / Hibernate with a MariaDB 10.4.16. The database belongs to a legacy system. For testing, I'd like to generate the schema from the entities.
src/test/resources/application.yml
spring:
datasource:
driver-class-name: org.mariadb.jdbc.Driver
jpa:
hibernate:
ddl-auto: create-drop
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
properties:
hibernate:
dialect:
storage-engine: innodb
format_sql: true
order_inserts: true
order_updates: true
use_sql_comments: true
Persisting to the database fails with:
Field 'id' doesn't have a default value
The entity class:
@Entity
@Table(name = "my_entity")
public class MyEntity implements Serializable {
private static final long serialVersionUID = 109811363263266332L;
@Id
@GeneratedValue
@Column(name = "id")
private long id;
@Column(name = "subject")
private String subject;
}
I tried changing the @GeneratedValue
strategies to AUTO
and IDENTITY
but none has an effect.
Update 1
After doing some more debugging, I found out that this behavior is caused by a custom generator (legacy codde) for the id. I didn't see this at glance. This custom generator is applied to other entities (haven't found out why yet) but not for MyEntity
.
@Id
@Access(PROPERTY)
@GenericGenerator(name = "IdOrGenerated", strategy = "MyCustomGenerator")
@GeneratedValue(strategy = IDENTITY, generator = "IdOrGenerated")
private long id;
@Override
public Serializable generate(SharedSessionContractImplementor session, Object object) {
Long id = (Long) session.getEntityPersister(null, object)
.getClassMetadata().getIdentifier(object, session);
return id != null && id != 0L ? id : defaultGenerator.generate(session, object);
}
This returns POST_INSERT_INDICATOR
:
https://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/id/IdentifierGeneratorHelper.html#POST_INSERT_INDICATOR
When replacing the custom generator, then it works. It also works if I explicitly call myEntity.setId(123L)
. Of course, that's not an option but it maybe provides some hint.