Skip to content

Commit

Permalink
Support not having any config for Panache if no real entities
Browse files Browse the repository at this point in the history
  • Loading branch information
gsmet committed Apr 9, 2019
1 parent 8fa5e40 commit 226edb6
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -115,39 +116,28 @@ HotDeploymentConfigFileBuildItem configFile() {
return new HotDeploymentConfigFileBuildItem("META-INF/persistence.xml");
}

@BuildStep
void doParseAndRegisterSubstrateResources(BuildProducer<PersistenceUnitDescriptorBuildItem> persistenceProducer,
BuildProducer<SubstrateResourceBuildItem> resourceProducer,
BuildProducer<HotDeploymentConfigFileBuildItem> hotDeploymentProducer,
BuildProducer<SystemPropertyBuildItem> systemPropertyProducer,
ArchiveRootBuildItem root,
ApplicationArchivesBuildItem applicationArchivesBuildItem,
Optional<DataSourceDriverBuildItem> driverBuildItem) throws IOException {
List<ParsedPersistenceXmlDescriptor> descriptors = loadOriginalXMLParsedDescriptors();
handleHibernateORMWithNoPersistenceXml(descriptors, resourceProducer, hotDeploymentProducer, systemPropertyProducer,
root, driverBuildItem, applicationArchivesBuildItem);
for (ParsedPersistenceXmlDescriptor i : descriptors) {
persistenceProducer.produce(new PersistenceUnitDescriptorBuildItem(i));
}
}

@BuildStep
@Record(STATIC_INIT)
public void build(RecorderContext recorder, HibernateOrmTemplate template,
List<PersistenceUnitDescriptorBuildItem> descItems,
List<AdditionalJpaModelBuildItem> additionalJpaModelBuildItems,
List<NonJpaModelBuildItem> nonJpaModelBuildItems,
CombinedIndexBuildItem index,
ApplicationIndexBuildItem applicationIndex,
BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
ArchiveRootBuildItem archiveRoot,
ApplicationArchivesBuildItem applicationArchivesBuildItem,
Optional<DataSourceDriverBuildItem> driverBuildItem,
BuildProducer<FeatureBuildItem> feature,
BuildProducer<PersistenceUnitDescriptorBuildItem> persistenceUnitDescriptorProducer,
BuildProducer<SubstrateResourceBuildItem> resourceProducer,
BuildProducer<HotDeploymentConfigFileBuildItem> hotDeploymentProducer,
BuildProducer<SystemPropertyBuildItem> systemPropertyProducer,
BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
BuildProducer<JpaEntitiesBuildItem> domainObjectsProducer,
BuildProducer<BeanContainerListenerBuildItem> beanContainerListener) throws Exception {

feature.produce(new FeatureBuildItem(FeatureBuildItem.HIBERNATE_ORM));

List<ParsedPersistenceXmlDescriptor> descriptors = descItems.stream()
.map(PersistenceUnitDescriptorBuildItem::getDescriptor).collect(Collectors.toList());
List<ParsedPersistenceXmlDescriptor> explicitDescriptors = loadOriginalXMLParsedDescriptors();

// build a composite index with additional jpa model classes
Indexer indexer = new Indexer();
Expand All @@ -161,7 +151,8 @@ public void build(RecorderContext recorder, HibernateOrmTemplate template,
Set<String> nonJpaModelClasses = nonJpaModelBuildItems.stream()
.map(NonJpaModelBuildItem::getClassName)
.collect(Collectors.toSet());
JpaJandexScavenger scavenger = new JpaJandexScavenger(reflectiveClass, descriptors, compositeIndex, nonJpaModelClasses);
JpaJandexScavenger scavenger = new JpaJandexScavenger(reflectiveClass, explicitDescriptors, compositeIndex,
nonJpaModelClasses);
final JpaEntitiesBuildItem domainObjects = scavenger.discoverModelAndRegisterForReflection();

// remember how to run the enhancers later
Expand All @@ -172,17 +163,28 @@ public void build(RecorderContext recorder, HibernateOrmTemplate template,
return;
}

for (String className : domainObjects.getClassNames()) {
template.callHibernateFeatureInit();

// handle the implicit persistence unit
List<ParsedPersistenceXmlDescriptor> allDescriptors = new ArrayList<>(explicitDescriptors.size() + 1);
allDescriptors.addAll(explicitDescriptors);
handleHibernateORMWithNoPersistenceXml(allDescriptors, resourceProducer, hotDeploymentProducer, systemPropertyProducer,
archiveRoot, driverBuildItem, applicationArchivesBuildItem);

for (ParsedPersistenceXmlDescriptor descriptor : allDescriptors) {
persistenceUnitDescriptorProducer.produce(new PersistenceUnitDescriptorBuildItem(descriptor));
}

for (String className : domainObjects.getEntityClassNames()) {
template.addEntity(className);
}
template.enlistPersistenceUnit();
template.callHibernateFeatureInit();

//set up the scanner, as this scanning has already been done we need to just tell it about the classes we
//have discovered. This scanner is bytecode serializable and is passed directly into the template
QuarkusScanner scanner = new QuarkusScanner();
Set<ClassDescriptor> classDescriptors = new HashSet<>();
for (String i : domainObjects.getClassNames()) {
for (String i : domainObjects.getAllModelClassNames()) {
QuarkusScanner.ClassDescriptorImpl desc = new QuarkusScanner.ClassDescriptorImpl(i,
ClassDescriptor.Categorization.MODEL);
classDescriptors.add(desc);
Expand All @@ -192,7 +194,7 @@ public void build(RecorderContext recorder, HibernateOrmTemplate template,
//now we serialize the XML and class list to bytecode, to remove the need to re-parse the XML on JVM startup
recorder.registerNonDefaultConstructor(ParsedPersistenceXmlDescriptor.class.getDeclaredConstructor(URL.class),
(i) -> Collections.singletonList(i.getPersistenceUnitRootUrl()));
beanContainerListener.produce(new BeanContainerListenerBuildItem(template.initMetadata(descriptors, scanner)));
beanContainerListener.produce(new BeanContainerListenerBuildItem(template.initMetadata(allDescriptors, scanner)));
}

@BuildStep
Expand Down Expand Up @@ -297,7 +299,7 @@ public void startPersistenceUnits(HibernateOrmTemplate template, BeanContainerBu
}

private boolean hasEntities(JpaEntitiesBuildItem jpaEntities, List<NonJpaModelBuildItem> nonJpaModels) {
return !jpaEntities.getClassNames().isEmpty() || !nonJpaModels.isEmpty();
return !jpaEntities.getEntityClassNames().isEmpty() || !nonJpaModels.isEmpty();
}

private boolean isUserDefinedProducerMissing(IndexView index, DotName annotationName) {
Expand Down Expand Up @@ -483,7 +485,7 @@ private void enhanceEntities(final JpaEntitiesBuildItem domainObjects,
List<AdditionalJpaModelBuildItem> additionalJpaModelBuildItems,
BuildProducer<GeneratedClassBuildItem> additionalClasses) {
HibernateEntityEnhancer hibernateEntityEnhancer = new HibernateEntityEnhancer();
for (String i : domainObjects.getClassNames()) {
for (String i : domainObjects.getAllModelClassNames()) {
transformers.produce(new BytecodeTransformerBuildItem(i, hibernateEntityEnhancer));
}
for (AdditionalJpaModelBuildItem additionalJpaModel : additionalJpaModelBuildItems) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;

import org.jboss.builder.item.SimpleBuildItem;

import io.quarkus.deployment.annotations.BuildProducer;
Expand All @@ -30,19 +32,35 @@
*/
public final class JpaEntitiesBuildItem extends SimpleBuildItem {

private final Set<String> classNames = new HashSet<String>();
private final Set<String> entityClassNames = new HashSet<String>();
private final Set<String> allModelClassNames = new HashSet<String>();

void addEntityClass(final String className) {
entityClassNames.add(className);
allModelClassNames.add(className);
}

void addEntity(final String className) {
classNames.add(className);
void addModelClass(final String className) {
allModelClassNames.add(className);
}

void registerAllForReflection(final BuildProducer<ReflectiveClassBuildItem> reflectiveClass) {
for (String className : classNames) {
for (String className : allModelClassNames) {
reflectiveClass.produce(new ReflectiveClassBuildItem(true, true, className));
}
}

public Set<String> getClassNames() {
return classNames;
/**
* @return the list of entities (i.e. classes marked with {@link Entity})
*/
public Set<String> getEntityClassNames() {
return entityClassNames;
}

/**
* @return the list of all model class names: entities, mapped super classes...
*/
public Set<String> getAllModelClassNames() {
return allModelClassNames;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import javax.persistence.Entity;
import javax.persistence.MappedSuperclass;

import org.graalvm.nativeimage.ImageInfo;
import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor;
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
import org.jboss.jandex.AnnotationInstance;
Expand Down Expand Up @@ -63,17 +62,17 @@ final class JpaJandexScavenger {

private static final DotName ENUM = DotName.createSimple(Enum.class.getName());

private final List<ParsedPersistenceXmlDescriptor> descriptors;
private final List<ParsedPersistenceXmlDescriptor> explicitDescriptors;
private final BuildProducer<ReflectiveClassBuildItem> reflectiveClass;
private final IndexView indexView;
private final Set<String> nonJpaModelClasses;

JpaJandexScavenger(BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
List<ParsedPersistenceXmlDescriptor> descriptors,
List<ParsedPersistenceXmlDescriptor> explicitDescriptors,
IndexView indexView,
Set<String> nonJpaModelClasses) {
this.reflectiveClass = reflectiveClass;
this.descriptors = descriptors;
this.explicitDescriptors = explicitDescriptors;
this.indexView = indexView;
this.nonJpaModelClasses = nonJpaModelClasses;
}
Expand All @@ -90,7 +89,7 @@ public JpaEntitiesBuildItem discoverModelAndRegisterForReflection() throws IOExc
enlistJPAModelClasses(indexView, domainObjectCollector, enumTypeCollector, MAPPED_SUPERCLASS, unindexedClasses);
enlistReturnType(indexView, domainObjectCollector, enumTypeCollector, unindexedClasses);

for (PersistenceUnitDescriptor pud : descriptors) {
for (PersistenceUnitDescriptor pud : explicitDescriptors) {
enlistExplicitClasses(indexView, domainObjectCollector, enumTypeCollector, pud.getManagedClassNames(),
unindexedClasses);
}
Expand Down Expand Up @@ -122,12 +121,11 @@ private static void enlistExplicitClasses(IndexView index, JpaEntitiesBuildItem
for (String className : managedClassNames) {
DotName dotName = DotName.createSimple(className);
boolean isInIndex = index.getClassByName(dotName) != null;
if (isInIndex) {
addClassHierarchyToReflectiveList(index, domainObjectCollector, enumTypeCollector, dotName, unindexedClasses);
} else {
if (!isInIndex) {
unindexedClasses.add(dotName);
domainObjectCollector.addEntity(className);
}

addClassHierarchyToReflectiveList(index, domainObjectCollector, enumTypeCollector, dotName, unindexedClasses);
}
}

Expand Down Expand Up @@ -175,7 +173,7 @@ private void enlistJPAModelClasses(IndexView index, JpaEntitiesBuildItem domainO
}
addClassHierarchyToReflectiveList(index, domainObjectCollector, enumTypeCollector, targetDotName,
unindexedClasses);
domainObjectCollector.addEntity(targetDotName.toString());
collectDomainObject(domainObjectCollector, klass);
}
}

Expand Down Expand Up @@ -208,7 +206,8 @@ private static void addClassHierarchyToReflectiveList(IndexView index, JpaEntiti
}

//Capture this one (for various needs: Reflective access enablement, Hibernate enhancement, JPA Template)
domainObjectCollector.addEntity(className.toString());
collectDomainObject(domainObjectCollector, classInfo);

// add superclass recursively
addClassHierarchyToReflectiveList(index, domainObjectCollector, enumTypeCollector, classInfo.superName(),
unindexedClasses);
Expand All @@ -218,4 +217,12 @@ private static void addClassHierarchyToReflectiveList(IndexView index, JpaEntiti
unindexedClasses);
}
}

private static void collectDomainObject(JpaEntitiesBuildItem domainObjectCollector, ClassInfo modelClass) {
if (modelClass.classAnnotation(JPA_ENTITY) != null) {
domainObjectCollector.addEntityClass(modelClass.name().toString());
} else {
domainObjectCollector.addModelClass(modelClass.name().toString());
}
}
}
11 changes: 3 additions & 8 deletions extensions/panache/hibernate-orm-panache/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,10 @@
<artifactId>asm-analysis</artifactId>
</dependency>

<!-- test dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus.gizmo</groupId>
<artifactId>gizmo</artifactId>
<type>test-jar</type>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5-internal</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.quarkus.hibernate.orm.panache.test;

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;

public class NoConfigTest {

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest().setArchiveProducer(
() -> ShrinkWrap.create(JavaArchive.class));

@Test
public void testNoConfig() {
// we should be able to start the application, even with no configuration at all
}
}

0 comments on commit 226edb6

Please sign in to comment.