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

entityManager.merge does not work in some cases #38722

Closed
alomine opened this issue Feb 10, 2024 · 11 comments · Fixed by #40102
Closed

entityManager.merge does not work in some cases #38722

alomine opened this issue Feb 10, 2024 · 11 comments · Fixed by #40102
Labels
area/hibernate-orm Hibernate ORM env/windows Impacts Windows machines kind/bug Something isn't working
Milestone

Comments

@alomine
Copy link

alomine commented Feb 10, 2024

Describe the bug

Hello!
In some cases hibernate entityManager.merge fails to update some fields when setting them to null. I have prepared some test cases to show when it works just fine and when it fails. Fails are when database fields are null except the one that needs to be set to null AND its not date field (which somehow works).

Case might be similar to:
#22080
and
#2815

Also if something is not clear or i need to provide more info, please feel free to ask

Expected behavior

All tests in given repository should pass

Actual behavior

2 of 6 tests fails. You can see in logs that update is not made

How to Reproduce?

Simply use .\mvnw test in my project

Output of uname -a or ver

Output of java -version

17

Quarkus version or git rev

3.7.2

Build tool (ie. output of mvnw --version or gradlew --version)

mvnw

Additional information

No response

@alomine alomine added the kind/bug Something isn't working label Feb 10, 2024
@quarkus-bot quarkus-bot bot added env/windows Impacts Windows machines triage/needs-triage labels Feb 10, 2024
@geoand geoand added area/hibernate-orm Hibernate ORM and removed triage/needs-triage labels Feb 12, 2024
Copy link

quarkus-bot bot commented Feb 12, 2024

/cc @gsmet (hibernate-orm), @yrodiere (hibernate-orm)

@yrodiere
Copy link
Member

Hey @alomine, thanks for reporting.
Are you sure this is specific to Quarkus? Can you reproduce with plain Hibernate ORM test case templates?

@yrodiere yrodiere added the triage/needs-feedback We are waiting for feedback. label Feb 12, 2024
@alomine
Copy link
Author

alomine commented Feb 12, 2024

Hello @yrodiere, thanks for response.
I'll try this. For now i can say two things - its not working in both quarkus 2.x.x version and 3.x.x (different hibernate versions) and its totally working on wildfly 26

@yrodiere
Copy link
Member

Thanks, looking forward to the reproducer.

@alomine
Copy link
Author

alomine commented Feb 12, 2024

@yrodiere
I did two test cases with plain hibernate based on examples that you posted. Both 7/7 successful

@gsmet
Copy link
Member

gsmet commented Feb 13, 2024

My guess is that it's related to the bytecode enhancement.

@Nikita-V0lkov
Copy link

I have some research on this issue.

1. Transactional annotation on the TestBugTest class instead of TestEntityService.

All tests will be passed, but the data in the database will not be updated.


2. QuarkusTransaction instead of annotation. You will have two possible variants:

2.1 Test fail, data not updated.

@Test
public void saveAndCheckWithNonNullNumber_test() {
    QuarkusTransaction.begin();
    testEntityService.clean();
    TestEntity testEntity = createEntityWithNonNullNumber();
    testEntityService.save(testEntity);
    QuarkusTransaction.commit();
    assertEquals(1, testEntityService.find(1L).getNumberField());
    
    QuarkusTransaction.begin();
    testEntity = createEntityWithAllNulls();
    testEntityService.update(testEntity);
    QuarkusTransaction.commit();
    assertEquals(null, testEntityService.find(1L).getNumberField());
}

2.2 Test passed, data not updated (similar to placing the Transactional annotation on the TestBugTest class).

@Test
public void saveAndCheckWithNonNullNumber_test() {
    QuarkusTransaction.begin();
    testEntityService.clean();
    TestEntity testEntity = createEntityWithNonNullNumber();
    testEntityService.save(testEntity);
    assertEquals(1, testEntityService.find(1L).getNumberField());
    QuarkusTransaction.commit();
    
    QuarkusTransaction.begin();
    testEntity = createEntityWithAllNulls();
    testEntityService.update(testEntity);
    assertEquals(null, testEntityService.find(1L).getNumberField());
    QuarkusTransaction.commit();
}

3. Update "refreshed" data after save (Transactional on TestEntityService).

3.1 Works as intended data in db updated.

@Test
public void saveAndCheckWithNonNullNumber_test() {
    testEntityService.clean();
    TestEntity testEntity = createEntityWithNonNullNumber();
    TestEntity savedEntity = testEntityService.save(testEntity);
    assertEquals(1, testEntityService.find(1L).getNumberField());
    
    savedEntity.setDateField(null);
    savedEntity.setNumberField(null);
    savedEntity.setStringField(null);
    testEntityService.update(savedEntity);
    assertEquals(null, testEntityService.find(1L).getNumberField());
}
public TestEntity save(TestEntity entity) {
    testEntityRepository.getEntityManager().persist(entity);
    testEntityRepository.getEntityManager().flush();
    testEntityRepository.getEntityManager().refresh(entity);
    return entity;
}

3.2 Save and find. Works similar to 3.1

@Test
public void saveAndCheckWithNonNullNumber_test() {
    testEntityService.clean();
    TestEntity testEntity = createEntityWithNonNullNumber();
    testEntityService.save(testEntity);
    assertEquals(1, testEntityService.find(1L).getNumberField());
    
    TestEntity savedEntity = testEntityService.find(1L);
    savedEntity.setDateField(null);
    savedEntity.setNumberField(null);
    savedEntity.setStringField(null);
    testEntityService.update(savedEntity);
    assertEquals(null, testEntityService.find(1L).getNumberField());
}

I hope this helps in some way.

@alomine
Copy link
Author

alomine commented Feb 15, 2024

Hello @Nikita-V0lkov,
in 3.1 and 3.2 entity you named as savedEntity is in persistent state and in this state this seems to be working. However by explicitly calling merge it shouldnt really matter.

@marko-bekhta
Copy link
Contributor

Hey,

I did two test cases with plain hibernate based on examples that you posted. Both 7/7 successful

As Guillaume suggested, you'd need to add bytecode enhancement to reproduce the issue with Hibernate ORM only. Here's a bug report based on this in ORM's JIRA: https://hibernate.atlassian.net/browse/HHH-17761

@yrodiere yrodiere added triage/upstream and removed triage/needs-feedback We are waiting for feedback. labels Feb 28, 2024
@alomine
Copy link
Author

alomine commented Feb 29, 2024

Is there a way to disable hibernate bytecode enhancement on quarkus ?

@yrodiere
Copy link
Member

There is not, and there are no plans to allow it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/hibernate-orm Hibernate ORM env/windows Impacts Windows machines kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants