Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@NotNull on JPA entity not respected in schema generation #31726

Closed
cowclaw opened this issue Nov 30, 2023 · 12 comments
Closed

@NotNull on JPA entity not respected in schema generation #31726

cowclaw opened this issue Nov 30, 2023 · 12 comments
Assignees
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) type: regression A bug that is also a regression
Milestone

Comments

@cowclaw
Copy link

cowclaw commented Nov 30, 2023

Affects: spring-orm 6.1.0 / 6.1.1:

During a spring boot update (3.1.5 to 3.2), I noticed that fields in entities that are annotated as jakarta.validation.constraints.NotNull no longer lead to the correct DDL statements.

Example:

@Entity
public class TestEntity {
	@Id
	private Long id;

	@NotNull
	private String name;
}

should trigger ddl statement that contains the not null constraint for the name attribute:

create table test_entity (
    id bigint not null,
    name varchar(255) not null,
    primary key (id)
);

but it does generate the following ddl statement without the not null constraint for the name attribute:

create table test_entity (
    id bigint not null,
    name varchar(255),
    primary key (id)
);

Note that @Column(nullable = false) does still work. Only @NotNull does not.

I was able to boil it down to the spring-orm update from 6.0.13 to 6.1.0 (which happens when updating spring boot as mentioned above).

Please see the following git project where I reproduced the issue: https://github.com/cowclaw/spring-orm-problem-demo

The commits tell the whole story:

  1. Show it works on spring boot 3.1.5
  2. Show it is broken on spring boot 3.2.0
  3. revert to spring boot 3.1.5
  4. Show its broken when selectively updating spring-orm

Included is a test that fails when the DDL statement does not meet the expectations.

Thanks for the great job you do on spring framework and thanks for having a look into the issue! 😄

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Nov 30, 2023
@bclozel
Copy link
Member

bclozel commented Nov 30, 2023

Spring is not responsible for the generation of the schema, this is a hibernate feature.

Downgrading your sample to use ext['hibernate.version'] = "6.1.7.Final" in build.gradle and adding logging.level.org.hibernate.SQL=debug in application.properties shows the following:

2023-11-30T14:09:42.066+01:00 DEBUG 73356 --- [           main] org.hibernate.SQL                        : create table test_entity (id bigint not null, name varchar(255) not null, primary key (id))

Please reach out to the Hibernate community if you need help.

@bclozel bclozel closed this as not planned Won't fix, can't repro, duplicate, stale Nov 30, 2023
@bclozel bclozel added status: invalid An issue that we don't feel is valid for: external-project Needs a fix in external project and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Nov 30, 2023
@cowclaw
Copy link
Author

cowclaw commented Nov 30, 2023

Thanks for your reply @bclozel.

I can not reproduce what you see. I created a branch combining hibernate 6.1.7.Final with spring-orm 6.1.1. It shows the same behaviour as before. The generated ddl statement lacks the not null.

2023-11-30T14:38:26.666+01:00  INFO 3040342 --- [    Test worker] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.1.7.Final
2023-11-30T14:38:26.795+01:00  INFO 3040342 --- [    Test worker] SQL dialect                              : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2023-11-30T14:38:27.065+01:00 DEBUG 3040342 --- [    Test worker] org.hibernate.SQL                        : 
    
    create table test_entity (
       id bigint not null,
        name varchar(255),
        primary key (id)
    )

Updating only hibernate to 6.3.1.Final and otherwise staying with the dependencies recommended by the spring boot plugin, the not null constraint is generated and the test is green as can be seen on the branch
My first guess was hibernate as well - but I was not able to show it.

@bclozel
Copy link
Member

bclozel commented Nov 30, 2023

You should not upgrade to spring-orm 6.1.1, as this leads to an invalid combination of dependencies. Spring Boot 3.1.x depends on Spring Framework 6.0.x: your application ends of with a mix of Spring Framework 6.0.x and 6.1.x versions.

Just using Spring Boot 3.1.5 dependency management and downgrading to Hibernate 6.1.7.Final works as expected.

@cowclaw
Copy link
Author

cowclaw commented Nov 30, 2023

Spring boot 3.1.5 does work without any changes to the hibernate version suggested by the spring boot plugin.

@bclozel
Copy link
Member

bclozel commented Nov 30, 2023

Reopening to further check for posssible regressions.

@bclozel bclozel reopened this Nov 30, 2023
@bclozel bclozel added status: waiting-for-triage An issue we've not yet triaged or decided on and removed status: invalid An issue that we don't feel is valid for: external-project Needs a fix in external project labels Nov 30, 2023
@bclozel
Copy link
Member

bclozel commented Nov 30, 2023

@cowclaw Sorry the conversation was confusing, I mixed things up locally with dependency management overrides and the dependency locking.

@jhoeller I've found that reverting locally #30549 makes it work. Is this a regression or is there a setup problem in the first place?

@bclozel bclozel added the in: data Issues in data modules (jdbc, orm, oxm, tx) label Nov 30, 2023
@jhoeller
Copy link
Contributor

So that processing reacts to the PersistenceUnitInfo.getValidationMode() setting? We set that to NONE if no validation provider is present, and to CALLBACK when a validation provider is present for the purpose of enforcing full error reporting for the provider bootstrap (e.g. failing when no EL provider is present which may otherwise remain unnoticed).

If some other code checks PersistenceUnitInfo.getValidationMode() and expects it to be something other than NONE even when no validation provider is present, I can see that being a problem indeed.

@bclozel
Copy link
Member

bclozel commented Nov 30, 2023

In this case the validation provider is present - with Spring Boot 3.1.5 I'm seeing AUTO and with 3.2.0 CALLBACK. I haven't figured out where this information is being picked up and how this influences the DDL generation or the metadata itself.

@jhoeller
Copy link
Contributor

jhoeller commented Dec 1, 2023

Maybe DDL generation only checks for == AUTO instead of != NONE when deciding whether to kick in?

If this remains unsolvable on the DDL side, we can also roll back our change. It was just meant to help for error reporting when the validation provider setup is incomplete.

@bclozel bclozel added type: regression A bug that is also a regression and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Dec 5, 2023
@bclozel bclozel added this to the 6.1.2 milestone Dec 5, 2023
@sbrannen sbrannen changed the title Regression in spring-orm 6.1.0 / 6.1.1: jakarta.validation.constraints.NotNull disrespected for ddl Regression in spring-orm 6.1.0 / 6.1.1: jakarta.validation.constraints.NotNull not respected for DDL Dec 5, 2023
@sbrannen sbrannen changed the title Regression in spring-orm 6.1.0 / 6.1.1: jakarta.validation.constraints.NotNull not respected for DDL Regression in spring-orm 6.1: jakarta.validation.constraints.NotNull not respected for DDL Dec 5, 2023
@bclozel bclozel changed the title Regression in spring-orm 6.1: jakarta.validation.constraints.NotNull not respected for DDL @NotNull on JPA entity not respected in schema generation Dec 5, 2023
@bclozel
Copy link
Member

bclozel commented Dec 6, 2023

I looked into this a bit more and found that bean validation constraints are not applied at all to the generated schema if the ValidationMode is CALLBACK. See this code snippet in hibernate-orm:

https://github.com/hibernate/hibernate-orm/blob/4a6c26ca4be5d5d0d750a8b5999ecaecd1688a9d/hibernate-core/src/main/java/org/hibernate/boot/beanvalidation/TypeSafeActivator.java#L143-L146

I have found an issue that suggests that as well as other cleanup tasks related to this validation mode support: https://hibernate.atlassian.net/browse/HHH-12287

In light of that, I will revert #30549 and add a note about this Hibernate issue to prevent further changes on our side.

@jordanms
Copy link

Is the fix released? I have this problem with Spring 6.1.4 (Spring Boot 3.2.3)

@bclozel
Copy link
Member

bclozel commented Mar 15, 2024

@jordanms yes this has been released with 6.1.2. You can create a new issue in this issue tracker if you manage to reproduce the problem with a minimal application (please attach this app as a zip to the issue or share the git repository URL).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) type: regression A bug that is also a regression
Projects
None yet
Development

No branches or pull requests

5 participants