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

Backport to 2.16: Upgrade to Hibernate ORM 5.6.15.Final #30956

Merged
merged 2 commits into from
Feb 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
<commons-lang3.version>3.12.0</commons-lang3.version>
<commons-codec.version>1.15</commons-codec.version>
<classmate.version>1.5.1</classmate.version>
<hibernate-orm.version>5.6.14.Final</hibernate-orm.version> <!-- When updating, align bytebuddy.version to Hibernate needs as well (just below): -->
<hibernate-orm.version>5.6.15.Final</hibernate-orm.version> <!-- When updating, align bytebuddy.version to Hibernate needs as well (just below): -->
<bytebuddy.version>1.12.18</bytebuddy.version> <!-- Version controlled by Hibernate ORM's needs -->
<hibernate-reactive.version>1.1.9.Final</hibernate-reactive.version>
<hibernate-validator.version>6.2.5.Final</hibernate-validator.version>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package io.quarkus.hibernate.orm.lazyloading;

import static io.quarkus.hibernate.orm.TransactionTestUtils.inTransaction;
import static org.assertj.core.api.Assertions.assertThat;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.transaction.UserTransaction;

import org.hibernate.resource.jdbc.spi.StatementInspector;
import org.junit.jupiter.api.Test;

public abstract class AbstractLazyBasicTest {
Expand All @@ -24,11 +30,61 @@ public AbstractLazyBasicTest(AccessDelegate delegate) {
}

@Test
public void update_all_nullToNonNull() {
public void update_all_nullToNull() {
initNull();
// Updating lazy properties always results in updates, even if the value didn't change,
// because we don't know of their previous value.
StatementSpy.checkAtLeastOneUpdate(() -> inTransaction(transaction, () -> {
delegate.updateAllProperties(em, entityId, null, null, null);
}));
inTransaction(transaction, () -> {
delegate.updateAllProperties(em, entityId, "updated1", "updated2", "updated3");
delegate.testLazyLoadingAndPersistedValues(em, entityId, null, null, null);
});
}

@Test
public void update_allLazy_nullToNull() {
initNull();
// Updating lazy properties always results in updates, even if the value didn't change,
// because we don't know of their previous value.
StatementSpy.checkAtLeastOneUpdate(() -> inTransaction(transaction, () -> {
delegate.updateAllLazyProperties(em, entityId, null, null);
}));
inTransaction(transaction, () -> {
delegate.testLazyLoadingAndPersistedValues(em, entityId, null, null, null);
});
}

@Test
public void update_oneEager_nullToNull() {
initNull();
StatementSpy.checkNoUpdate(() -> inTransaction(transaction, () -> {
delegate.updateOneEagerProperty(em, entityId, null);
}));
inTransaction(transaction, () -> {
delegate.testLazyLoadingAndPersistedValues(em, entityId, null, null, null);
});
}

@Test
public void update_oneLazy_nullToNull() {
initNull();
// Updating lazy properties always results in updates, even if the value didn't change,
// because we don't know of their previous value.
StatementSpy.checkAtLeastOneUpdate(() -> inTransaction(transaction, () -> {
delegate.updateOneLazyProperty(em, entityId, null);
}));
inTransaction(transaction, () -> {
delegate.testLazyLoadingAndPersistedValues(em, entityId, null, null, null);
});
}

@Test
public void update_all_nullToNonNull() {
initNull();
StatementSpy.checkAtLeastOneUpdate(() -> inTransaction(transaction, () -> {
delegate.updateAllProperties(em, entityId, "updated1", "updated2", "updated3");
}));
inTransaction(transaction, () -> {
delegate.testLazyLoadingAndPersistedValues(em, entityId, "updated1", "updated2", "updated3");
});
Expand All @@ -37,9 +93,9 @@ public void update_all_nullToNonNull() {
@Test
public void update_allLazy_nullToNonNull() {
initNull();
inTransaction(transaction, () -> {
StatementSpy.checkAtLeastOneUpdate(() -> inTransaction(transaction, () -> {
delegate.updateAllLazyProperties(em, entityId, "updated1", "updated2");
});
}));
inTransaction(transaction, () -> {
delegate.testLazyLoadingAndPersistedValues(em, entityId, null, "updated1", "updated2");
});
Expand All @@ -48,9 +104,9 @@ public void update_allLazy_nullToNonNull() {
@Test
public void update_oneEager_nullToNonNull() {
initNull();
inTransaction(transaction, () -> {
StatementSpy.checkAtLeastOneUpdate(() -> inTransaction(transaction, () -> {
delegate.updateOneEagerProperty(em, entityId, "updated1");
});
}));
inTransaction(transaction, () -> {
delegate.testLazyLoadingAndPersistedValues(em, entityId, "updated1", null, null);
});
Expand All @@ -59,64 +115,112 @@ public void update_oneEager_nullToNonNull() {
@Test
public void update_oneLazy_nullToNonNull() {
initNull();
inTransaction(transaction, () -> {
StatementSpy.checkAtLeastOneUpdate(() -> inTransaction(transaction, () -> {
delegate.updateOneLazyProperty(em, entityId, "updated2");
});
}));
inTransaction(transaction, () -> {
delegate.testLazyLoadingAndPersistedValues(em, entityId, null, "updated2", null);
});
}

@Test
public void update_all_nonNullToNonNull() {
public void update_all_nonNullToNonNull_differentValue() {
initNonNull();
inTransaction(transaction, () -> {
StatementSpy.checkAtLeastOneUpdate(() -> inTransaction(transaction, () -> {
delegate.updateAllProperties(em, entityId, "updated1", "updated2", "updated3");
});
}));
inTransaction(transaction, () -> {
delegate.testLazyLoadingAndPersistedValues(em, entityId, "updated1", "updated2", "updated3");
});
}

@Test
public void update_allLazy_nonNullToNonNull() {
public void update_all_nonNullToNonNull_sameValue() {
initNonNull();
// Updating lazy properties always results in updates, even if the value didn't change,
// because we don't know of their previous value.
StatementSpy.checkAtLeastOneUpdate(() -> inTransaction(transaction, () -> {
delegate.updateAllProperties(em, entityId, "initial1", "initial2", "initial3");
}));
inTransaction(transaction, () -> {
delegate.updateAllLazyProperties(em, entityId, "updated1", "updated2");
delegate.testLazyLoadingAndPersistedValues(em, entityId, "initial1", "initial2", "initial3");
});
}

@Test
public void update_allLazy_nonNullToNonNull_differentValue() {
initNonNull();
StatementSpy.checkAtLeastOneUpdate(() -> inTransaction(transaction, () -> {
delegate.updateAllLazyProperties(em, entityId, "updated1", "updated2");
}));
inTransaction(transaction, () -> {
delegate.testLazyLoadingAndPersistedValues(em, entityId, "initial1", "updated1", "updated2");
});
}

@Test
public void update_oneEager_nonNullToNonNull() {
public void update_allLazy_nonNullToNonNull_sameValue() {
initNonNull();
// Updating lazy properties always results in updates, even if the value didn't change,
// because we don't know of their previous value.
StatementSpy.checkAtLeastOneUpdate(() -> inTransaction(transaction, () -> {
delegate.updateAllLazyProperties(em, entityId, "initial2", "initial3");
}));
inTransaction(transaction, () -> {
delegate.updateOneEagerProperty(em, entityId, "updated1");
delegate.testLazyLoadingAndPersistedValues(em, entityId, "initial1", "initial2", "initial3");
});
}

@Test
public void update_oneEager_nonNullToNonNull_differentValue() {
initNonNull();
StatementSpy.checkAtLeastOneUpdate(() -> inTransaction(transaction, () -> {
delegate.updateOneEagerProperty(em, entityId, "updated1");
}));
inTransaction(transaction, () -> {
delegate.testLazyLoadingAndPersistedValues(em, entityId, "updated1", "initial2", "initial3");
});
}

@Test
public void update_oneLazy_nonNullToNonNull() {
public void update_oneEager_nonNullToNonNull_sameValue() {
initNonNull();
StatementSpy.checkNoUpdate(() -> inTransaction(transaction, () -> {
delegate.updateOneEagerProperty(em, entityId, "initial1");
}));
inTransaction(transaction, () -> {
delegate.updateOneLazyProperty(em, entityId, "updated2");
delegate.testLazyLoadingAndPersistedValues(em, entityId, "initial1", "initial2", "initial3");
});
}

@Test
public void update_oneLazy_nonNullToNonNull_differentValue() {
initNonNull();
StatementSpy.checkAtLeastOneUpdate(() -> inTransaction(transaction, () -> {
delegate.updateOneLazyProperty(em, entityId, "updated2");
}));
inTransaction(transaction, () -> {
delegate.testLazyLoadingAndPersistedValues(em, entityId, "initial1", "updated2", "initial3");
});
}

@Test
public void update_all_nonNullToNull() {
public void update_oneLazy_nonNullToNonNull_sameValue() {
initNonNull();
StatementSpy.checkAtLeastOneUpdate(() -> inTransaction(transaction, () -> {
delegate.updateOneLazyProperty(em, entityId, "initial2");
}));
inTransaction(transaction, () -> {
delegate.updateAllProperties(em, entityId, null, null, null);
delegate.testLazyLoadingAndPersistedValues(em, entityId, "initial1", "initial2", "initial3");
});
}

@Test
public void update_all_nonNullToNull() {
initNonNull();
StatementSpy.checkAtLeastOneUpdate(() -> inTransaction(transaction, () -> {
delegate.updateAllProperties(em, entityId, null, null, null);
}));
inTransaction(transaction, () -> {
delegate.testLazyLoadingAndPersistedValues(em, entityId, null, null, null);
});
Expand All @@ -125,9 +229,9 @@ public void update_all_nonNullToNull() {
@Test
public void update_allLazy_nonNullToNull() {
initNonNull();
inTransaction(transaction, () -> {
StatementSpy.checkAtLeastOneUpdate(() -> inTransaction(transaction, () -> {
delegate.updateAllLazyProperties(em, entityId, null, null);
});
}));
inTransaction(transaction, () -> {
delegate.testLazyLoadingAndPersistedValues(em, entityId, "initial1", null, null);
});
Expand All @@ -136,9 +240,9 @@ public void update_allLazy_nonNullToNull() {
@Test
public void update_oneEager_nonNullToNull() {
initNonNull();
inTransaction(transaction, () -> {
StatementSpy.checkAtLeastOneUpdate(() -> inTransaction(transaction, () -> {
delegate.updateOneEagerProperty(em, entityId, null);
});
}));
inTransaction(transaction, () -> {
delegate.testLazyLoadingAndPersistedValues(em, entityId, null, "initial2", "initial3");
});
Expand All @@ -147,9 +251,9 @@ public void update_oneEager_nonNullToNull() {
@Test
public void update_oneLazy_nonNullToNull() {
initNonNull();
inTransaction(transaction, () -> {
StatementSpy.checkAtLeastOneUpdate(() -> inTransaction(transaction, () -> {
delegate.updateOneLazyProperty(em, entityId, null);
});
}));
inTransaction(transaction, () -> {
delegate.testLazyLoadingAndPersistedValues(em, entityId, "initial1", null, "initial3");
});
Expand Down Expand Up @@ -197,4 +301,40 @@ void testLazyLoadingAndPersistedValues(EntityManager entityManager, long entityI
String expectedLazyProperty1,
String expectedLazyProperty2);
}

public static class StatementSpy implements StatementInspector {
private static final ThreadLocal<List<String>> statements = new ThreadLocal<>();

public static void checkAtLeastOneUpdate(Runnable runnable) {
check(runnable, list -> assertThat(list)
.isNotEmpty() // Something is wrong if we didn't even load an entity
.anySatisfy(sql -> assertThat(sql).containsIgnoringCase("update")));
}

public static void checkNoUpdate(Runnable runnable) {
check(runnable, list -> assertThat(list)
.isNotEmpty() // Something is wrong if we didn't even load an entity
.allSatisfy(sql -> assertThat(sql).doesNotContainIgnoringCase("update")));
}

public static void check(Runnable runnable, Consumer<List<String>> assertion) {
List<String> list = new ArrayList<>();
if (statements.get() != null) {
throw new IllegalStateException("Cannot nest checkNoUpdate()");
}
statements.set(list);
runnable.run();
statements.remove();
assertion.accept(list);
}

@Override
public String inspect(String sql) {
List<String> list = statements.get();
if (list != null) {
list.add(sql);
}
return sql;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ public class LazyBasicDefaultGroupTest extends AbstractLazyBasicTest {
.addClass(MyEntity.class)
.addClass(AccessDelegate.class)
.addClass(AccessDelegateImpl.class))
.withConfigurationResource("application.properties");
.withConfigurationResource("application.properties")
.overrideConfigKey("quarkus.hibernate-orm.unsupported-properties.\"hibernate.session_factory.statement_inspector\"",
StatementSpy.class.getName());

public LazyBasicDefaultGroupTest() {
super(new AccessDelegateImpl());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ public class LazyBasicMultiNonDefaultGroupTest extends AbstractLazyBasicTest {
.addClass(MyEntity.class)
.addClass(AccessDelegate.class)
.addClass(AccessDelegateImpl.class))
.withConfigurationResource("application.properties");
.withConfigurationResource("application.properties")
.overrideConfigKey("quarkus.hibernate-orm.unsupported-properties.\"hibernate.session_factory.statement_inspector\"",
StatementSpy.class.getName());

public LazyBasicMultiNonDefaultGroupTest() {
super(new AccessDelegateImpl());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ public class LazyBasicNonDefaultGroupTest extends AbstractLazyBasicTest {
.addClass(MyEntity.class)
.addClass(AccessDelegate.class)
.addClass(AccessDelegateImpl.class))
.withConfigurationResource("application.properties");
.withConfigurationResource("application.properties")
.overrideConfigKey("quarkus.hibernate-orm.unsupported-properties.\"hibernate.session_factory.statement_inspector\"",
StatementSpy.class.getName());

public LazyBasicNonDefaultGroupTest() {
super(new AccessDelegateImpl());
Expand Down