Skip to content

Commit

Permalink
Merge pull request #42190 from peuBouzon/fix-41992
Browse files Browse the repository at this point in the history
Improve error message when multiple hibernate interceptors are found
  • Loading branch information
yrodiere authored Jul 29, 2024
2 parents ef00efc + 25626f3 commit b31c632
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package io.quarkus.hibernate.orm.boot;

import static org.assertj.core.api.Assertions.assertThat;

import org.hibernate.Interceptor;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.hibernate.orm.MyEntity;
import io.quarkus.hibernate.orm.PersistenceUnitExtension;
import io.quarkus.test.QuarkusUnitTest;

public class AmbiguousPersistenceUnitExtensionTest {

@RegisterExtension
static QuarkusUnitTest runner = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar
.addClass(MyEntity.class)
.addClass(PersistenceUnitInterceptor.class)
.addClass(AnotherPersistenceUnitInterceptor.class))
.withConfigurationResource("application.properties")
.assertException(throwable -> assertThat(throwable)
.hasNoSuppressedExceptions()
.rootCause()
.hasMessageContainingAll("Multiple instances of Interceptor were found for persistence unit <default>.",
"At most one instance can be assigned to each persistence unit. Instances found:",
"io.quarkus.hibernate.orm.boot.AmbiguousPersistenceUnitExtensionTest.PersistenceUnitInterceptor",
"io.quarkus.hibernate.orm.boot.AmbiguousPersistenceUnitExtensionTest.AnotherPersistenceUnitInterceptor"));

@PersistenceUnitExtension
public static class PersistenceUnitInterceptor implements Interceptor {
}

@PersistenceUnitExtension
public static class AnotherPersistenceUnitInterceptor implements Interceptor {
}

@Test
public void test() {
Assertions.fail("Startup should have failed");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;

import jakarta.enterprise.inject.Default;
Expand Down Expand Up @@ -30,10 +31,12 @@ public static <T> InjectableInstance<T> singleExtensionInstanceForPersistenceUni
InjectableInstance<T> instance = extensionInstanceForPersistenceUnit(beanType, persistenceUnitName,
additionalQualifiers);
if (instance.isAmbiguous()) {
List<String> ambiguousClassNames = instance.handlesStream().map(h -> h.getBean().getBeanClass().getCanonicalName())
.toList();
throw new IllegalStateException(String.format(Locale.ROOT,
"Multiple instances of %1$s were found for persistence unit %2$s. "
+ "At most one instance can be assigned to each persistence unit.",
beanType.getSimpleName(), persistenceUnitName));
+ "At most one instance can be assigned to each persistence unit. Instances found: %3$s",
beanType.getSimpleName(), persistenceUnitName, ambiguousClassNames));
}
return instance;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package io.quarkus.hibernate.search.orm.elasticsearch.test.boot;

import static org.assertj.core.api.Assertions.assertThat;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;

import org.hibernate.search.engine.reporting.EntityIndexingFailureContext;
import org.hibernate.search.engine.reporting.FailureContext;
import org.hibernate.search.engine.reporting.FailureHandler;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.hibernate.search.orm.elasticsearch.SearchExtension;
import io.quarkus.test.QuarkusUnitTest;

public class AmbiguousSearchExtensionTest {

@RegisterExtension
static QuarkusUnitTest runner = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar
.addClass(MyEntity.class)
.addClass(SearchFailureHandler.class)
.addClass(AnotherSearchFailureHandler.class)
.addAsResource("application.properties"))
.assertException(throwable -> assertThat(throwable)
.hasNoSuppressedExceptions()
.rootCause()
.hasMessageContainingAll(
"Multiple instances of FailureHandler were found for Hibernate Search in persistence unit <default>.",
"At most one instance can be assigned to each persistence unit. Instances found:",
"io.quarkus.hibernate.search.orm.elasticsearch.test.boot.AmbiguousSearchExtensionTest.SearchFailureHandler",
"io.quarkus.hibernate.search.orm.elasticsearch.test.boot.AmbiguousSearchExtensionTest.AnotherSearchFailureHandler"));

@Entity
@Indexed
static class MyEntity {

@Id
@GeneratedValue
private Long id;
}

@SearchExtension
public static class SearchFailureHandler implements FailureHandler {
@Override
public void handle(FailureContext failureContext) {
}

@Override
public void handle(EntityIndexingFailureContext entityIndexingFailureContext) {
}
}

@SearchExtension
public static class AnotherSearchFailureHandler implements FailureHandler {
@Override
public void handle(FailureContext failureContext) {
}

@Override
public void handle(EntityIndexingFailureContext entityIndexingFailureContext) {
}
}

@Test
public void test() {
Assertions.fail("Startup should have failed");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,23 @@ private static <T> Optional<BeanReference<T>> singleExtensionBeanReferenceFor(Cl
String persistenceUnitName, String backendName, String indexName) {
InjectableInstance<T> instance = extensionInstanceFor(beanType, persistenceUnitName, backendName, indexName);
if (instance.isAmbiguous()) {
List<String> ambiguousClassNames = instance.handlesStream().map(h -> h.getBean().getBeanClass().getCanonicalName())
.toList();
if (indexName != null) {
throw new IllegalStateException(String.format(Locale.ROOT,
"Multiple instances of %1$s were found for Hibernate Search index %3$s in persistence unit %2$s."
+ " At most one instance can be assigned to each index.",
beanType.getSimpleName(), persistenceUnitName, indexName));
"Multiple instances of %1$s were found for Hibernate Search index %2$s in persistence unit %3$s."
+ " At most one instance can be assigned to each index. Instances found: %4$s",
beanType.getSimpleName(), indexName, persistenceUnitName, ambiguousClassNames));
} else if (backendName != null) {
throw new IllegalStateException(String.format(Locale.ROOT,
"Multiple instances of %1$s were found for Hibernate Search backend %3$s in persistence unit %2$s."
+ " At most one instance can be assigned to each backend.",
beanType.getSimpleName(), persistenceUnitName, backendName));
"Multiple instances of %1$s were found for Hibernate Search backend %2$s in persistence unit %3$s."
+ " At most one instance can be assigned to each backend. Instances found: %4$s",
beanType.getSimpleName(), backendName, persistenceUnitName, ambiguousClassNames));
} else {
throw new IllegalStateException(String.format(Locale.ROOT,
"Multiple instances of %1$s were found for Hibernate Search in persistence unit %2$s."
+ " At most one instance can be assigned to each persistence unit.",
beanType.getSimpleName(), persistenceUnitName));
+ " At most one instance can be assigned to each persistence unit. Instances found: %3$s",
beanType.getSimpleName(), persistenceUnitName, ambiguousClassNames));
}
}
return instance.isResolvable() ? Optional.of(new ArcBeanReference<>(instance.getHandle().getBean())) : Optional.empty();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package io.quarkus.hibernate.search.standalone.elasticsearch.test.boot;

import static org.assertj.core.api.Assertions.assertThat;

import org.hibernate.search.engine.reporting.EntityIndexingFailureContext;
import org.hibernate.search.engine.reporting.FailureContext;
import org.hibernate.search.engine.reporting.FailureHandler;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.DocumentId;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.SearchEntity;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.hibernate.search.standalone.elasticsearch.SearchExtension;
import io.quarkus.test.QuarkusUnitTest;

public class AmbiguousSearchExtensionTest {
@RegisterExtension
static QuarkusUnitTest runner = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar
.addClass(MyEntity.class)
.addClass(SearchFailureHandler.class)
.addClass(AnotherSearchFailureHandler.class)
.addAsResource("application.properties"))
.assertException(throwable -> assertThat(throwable)
.hasNoSuppressedExceptions()
.rootCause()
.hasMessageContainingAll(
"Multiple instances of FailureHandler were found for Hibernate Search Standalone.",
"At most one instance can be assigned. Instances found:",
"io.quarkus.hibernate.search.standalone.elasticsearch.test.boot.AmbiguousSearchExtensionTest.SearchFailureHandler",
"io.quarkus.hibernate.search.standalone.elasticsearch.test.boot.AmbiguousSearchExtensionTest.AnotherSearchFailureHandler"));

@SearchEntity
@Indexed
public static class MyEntity {
@DocumentId
private Long id;
}

@SearchExtension
public static class SearchFailureHandler implements FailureHandler {
@Override
public void handle(FailureContext failureContext) {
}

@Override
public void handle(EntityIndexingFailureContext entityIndexingFailureContext) {
}
}

@SearchExtension
public static class AnotherSearchFailureHandler implements FailureHandler {
@Override
public void handle(FailureContext failureContext) {
}

@Override
public void handle(EntityIndexingFailureContext entityIndexingFailureContext) {
}
}

@Test
public void test() {
Assertions.fail("Startup should have failed");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,23 @@ private static <T> Optional<BeanReference<T>> singleExtensionBeanReferenceFor(Cl
String backendName, String indexName) {
InjectableInstance<T> instance = extensionInstanceFor(beanType, backendName, indexName);
if (instance.isAmbiguous()) {
List<String> ambiguousClassNames = instance.handlesStream().map(h -> h.getBean().getBeanClass().getCanonicalName())
.toList();
if (indexName != null) {
throw new IllegalStateException(String.format(Locale.ROOT,
"Multiple instances of %1$s were found for Hibernate Search Standalone index %2$s."
+ " At most one instance can be assigned to each index.",
beanType.getSimpleName(), indexName));
+ " At most one instance can be assigned to each index. Instances found: %3$s",
beanType.getSimpleName(), indexName, ambiguousClassNames));
} else if (backendName != null) {
throw new IllegalStateException(String.format(Locale.ROOT,
"Multiple instances of %1$s were found for Hibernate Search Standalone backend %2$s."
+ " At most one instance can be assigned to each backend.",
beanType.getSimpleName(), backendName));
+ " At most one instance can be assigned to each backend. Instances found: %3$s",
beanType.getSimpleName(), backendName, ambiguousClassNames));
} else {
throw new IllegalStateException(String.format(Locale.ROOT,
"Multiple instances of %1$s were found for Hibernate Search Standalone."
+ " At most one instance can be assigned.",
beanType.getSimpleName()));
+ " At most one instance can be assigned. Instances found: %2$s",
beanType.getSimpleName(), ambiguousClassNames));
}
}
return instance.isResolvable() ? Optional.of(new ArcBeanReference<>(instance.getHandle().getBean())) : Optional.empty();
Expand Down

0 comments on commit b31c632

Please sign in to comment.