Skip to content

Commit

Permalink
Merge pull request #15835 from DavideD/15834-Joined
Browse files Browse the repository at this point in the history
Error when running HQL queries spanning multiple tables in Hibernate Reactive
  • Loading branch information
Sanne authored Mar 18, 2021
2 parents 11fe7a8 + 5a43e18 commit e43fc0a
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@
public final class HibernateReactiveProcessor {

private static final String HIBERNATE_REACTIVE = "Hibernate Reactive";
static final String[] REFLECTIVE_CONSTRUCTORS_NEEDED = {
"org.hibernate.reactive.persister.entity.impl.ReactiveSingleTableEntityPersister",
"org.hibernate.reactive.persister.entity.impl.ReactiveJoinedSubclassEntityPersister",
"org.hibernate.reactive.persister.entity.impl.ReactiveUnionSubclassEntityPersister",
"org.hibernate.reactive.persister.collection.impl.ReactiveOneToManyPersister",
"org.hibernate.reactive.persister.collection.impl.ReactiveBasicCollectionPersister",
};

@BuildStep
FeatureBuildItem feature() {
Expand Down Expand Up @@ -92,11 +99,7 @@ void registerBeans(BuildProducer<AdditionalBeanBuildItem> additionalBeans, Combi

@BuildStep
void reflections(BuildProducer<ReflectiveClassBuildItem> reflectiveClass) {
String[] classes = {
"org.hibernate.reactive.persister.entity.impl.ReactiveSingleTableEntityPersister",
"org.hibernate.reactive.persister.collection.impl.ReactiveOneToManyPersister"
};
reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, classes));
reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, REFLECTIVE_CONSTRUCTORS_NEEDED));
}

@BuildStep
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.quarkus.hibernate.reactive.deployment;

import org.junit.jupiter.api.Test;

public final class PersisterNamesTest {

@Test
public void testClassesExist() {
for (String clazz : HibernateReactiveProcessor.REFLECTIVE_CONSTRUCTORS_NEEDED) {
assertClassExists(clazz);
}
}

private void assertClassExists(String clazz) {
try {
Thread.currentThread().getContextClassLoader().loadClass(clazz);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.hibernate.boot.internal.SessionFactoryOptionsBuilder;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.reactive.bulk.impl.ReactiveBulkIdStrategy;
import org.hibernate.reactive.session.impl.ReactiveSessionFactoryImpl;

import io.quarkus.hibernate.orm.runtime.PersistenceUnitUtil;
Expand All @@ -26,6 +27,7 @@ public FastBootReactiveEntityManagerFactoryBuilder(PrevalidatedQuarkusMetadata m
public EntityManagerFactory build() {
final SessionFactoryOptionsBuilder optionsBuilder = metadata.buildSessionFactoryOptionsBuilder();
optionsBuilder.enableCollectionInDefaultFetchGroup(true);
optionsBuilder.applyMultiTableBulkIdStrategy(new ReactiveBulkIdStrategy(metadata));
populate(PersistenceUnitUtil.DEFAULT_PERSISTENCE_UNIT_NAME, optionsBuilder, standardServiceRegistry,
multiTenancyStrategy);
SessionFactoryOptions options = optionsBuilder.buildOptions();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package io.quarkus.it.hibernate.reactive.postgresql;

import java.util.Objects;

import javax.inject.Inject;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import javax.ws.rs.DELETE;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;

import org.hibernate.reactive.mutiny.Mutiny;

import io.smallrye.mutiny.Uni;

/**
* We want to check that the right {@link org.hibernate.hql.spi.id.MultiTableBulkIdStrategy}
* is set when using Hibernate Reactive.
*
* @see io.quarkus.hibernate.reactive.runtime.boot.FastBootReactiveEntityManagerFactoryBuilder
* @see org.hibernate.reactive.bulk.impl.ReactiveBulkIdStrategy
*/
@Path("/hr-joinedsubclass")
public class HibernateReactiveTestEndpointJoinedSubclass {

@Inject
Mutiny.Session session;

@DELETE
@Path("/deleteBook/{bookId}")
public Uni<Book> deleteBook(@PathParam("bookId") Integer bookId) {
return session.withTransaction(tx -> session
.createQuery("delete BookJS where id=:id")
.setParameter("id", bookId)
.executeUpdate())
.chain(() -> session.find(SpellBook.class, bookId));
}

@POST
@Path("/prepareDb")
public Uni<Void> prepareDb() {
final SpellBook spells = new SpellBook(6, "Necronomicon", true);

return session.persist(spells)
.chain(session::flush);
}

@Entity(name = "SpellBookJS")
@Table(name = "SpellBookJS")
@DiscriminatorValue("S")
public static class SpellBook extends Book {

private boolean forbidden;

public SpellBook(Integer id, String title, boolean forbidden) {
super(id, title);
this.forbidden = forbidden;
}

SpellBook() {
}

public boolean getForbidden() {
return forbidden;
}
}

@Entity(name = "BookJS")
@Table(name = "BookJS")
@Inheritance(strategy = InheritanceType.JOINED)
public static class Book {

@Id
private Integer id;
private String title;

public Book() {
}

public Book(Integer id, String title) {
this.id = id;
this.title = title;
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Book book = (Book) o;
return Objects.equals(title, book.title);
}

@Override
public int hashCode() {
return Objects.hash(title);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.quarkus.it.hibernate.reactive.postgresql;

import io.quarkus.test.junit.NativeImageTest;

@NativeImageTest
public class HibernateReactiveJoinedSubclassInGraalIT extends HibernateReactiveJoinedSubclassTest {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.quarkus.it.hibernate.reactive.postgresql;

import static org.hamcrest.Matchers.emptyOrNullString;

import org.junit.jupiter.api.Test;

import io.quarkus.test.common.http.TestHTTPEndpoint;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.RestAssured;

@QuarkusTest
@TestHTTPEndpoint(HibernateReactiveTestEndpointJoinedSubclass.class)
public class HibernateReactiveJoinedSubclassTest {

@Test
public void deleteBookQuery() {
RestAssured.when()
.post("/prepareDb")
.then()
.statusCode(204);

RestAssured.when()
.delete("/deleteBook/6")
.then()
.statusCode(204)
.body(emptyOrNullString());
}
}

0 comments on commit e43fc0a

Please sign in to comment.