下面列出了怎么用org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor的API类实例代码及写法,或者点击链接到github查看源代码。
@BuildStep
public ProxyDefinitionsBuildItem pregenProxies(
JpaEntitiesBuildItem domainObjects,
JpaModelIndexBuildItem indexBuildItem,
List<PersistenceUnitDescriptorBuildItem> persistenceUnitDescriptorBuildItems,
BuildProducer<GeneratedClassBuildItem> generatedClassBuildItemBuildProducer) {
Set<String> entitiesToGenerateProxiesFor = new HashSet<>(domainObjects.getEntityClassNames());
List<ParsedPersistenceXmlDescriptor> allDescriptors = new ArrayList<>();
for (PersistenceUnitDescriptorBuildItem pud : persistenceUnitDescriptorBuildItems) {
allDescriptors.add(pud.getDescriptor());
}
for (ParsedPersistenceXmlDescriptor unit : allDescriptors) {
entitiesToGenerateProxiesFor.addAll(unit.getManagedClassNames());
}
PreGeneratedProxies proxyDefinitions = generatedProxies(entitiesToGenerateProxiesFor, indexBuildItem.getIndex(),
generatedClassBuildItemBuildProducer);
return new ProxyDefinitionsBuildItem(proxyDefinitions);
}
public static EntityManagerFactory createEntityManagerFactory(KeycloakSession session, String unitName, Map<String, Object> properties, boolean jta) {
PersistenceUnitTransactionType txType = jta ? PersistenceUnitTransactionType.JTA : PersistenceUnitTransactionType.RESOURCE_LOCAL;
List<ParsedPersistenceXmlDescriptor> persistenceUnits = PersistenceXmlParser.locatePersistenceUnits(properties);
for (ParsedPersistenceXmlDescriptor persistenceUnit : persistenceUnits) {
if (persistenceUnit.getName().equals(unitName)) {
List<Class<?>> providedEntities = getProvidedEntities(session);
for (Class<?> entityClass : providedEntities) {
// Add all extra entity classes to the persistence unit.
persistenceUnit.addClasses(entityClass.getName());
}
// Now build the entity manager factory, supplying a proxy classloader, so Hibernate will be able
// to find and load the extra provided entities.
persistenceUnit.setTransactionType(txType);
return Bootstrap.getEntityManagerFactoryBuilder(persistenceUnit, properties,
new ProxyClassLoader(providedEntities)).build();
}
}
throw new RuntimeException("Persistence unit '" + unitName + "' not found");
}
@BuildStep
public void parsePersistenceXmlDescriptors(
BuildProducer<PersistenceXmlDescriptorBuildItem> persistenceXmlDescriptorBuildItemBuildProducer) {
if (!shouldIgnorePersistenceXmlResources()) {
List<ParsedPersistenceXmlDescriptor> explicitDescriptors = QuarkusPersistenceXmlParser.locatePersistenceUnits();
for (ParsedPersistenceXmlDescriptor desc : explicitDescriptors) {
persistenceXmlDescriptorBuildItemBuildProducer.produce(new PersistenceXmlDescriptorBuildItem(desc));
}
}
}
public BeanContainerListener initMetadata(List<ParsedPersistenceXmlDescriptor> parsedPersistenceXmlDescriptors,
Scanner scanner, Collection<Class<? extends Integrator>> additionalIntegrators,
PreGeneratedProxies proxyDefinitions, MultiTenancyStrategy strategy) {
return new BeanContainerListener() {
@Override
public void created(BeanContainer beanContainer) {
PersistenceUnitsHolder.initializeJpa(parsedPersistenceXmlDescriptors, scanner, additionalIntegrators,
proxyDefinitions, strategy);
}
};
}
private static List<PersistenceUnitDescriptor> convertPersistenceUnits(
final List<ParsedPersistenceXmlDescriptor> parsedPersistenceXmlDescriptors) {
try {
return parsedPersistenceXmlDescriptors.stream().map(LightPersistenceXmlDescriptor::new)
.collect(Collectors.toList());
} catch (Exception e) {
throw new PersistenceException("Unable to locate persistence units", e);
}
}
@BuildStep
public void buildReactivePersistenceUnit(
DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig,
List<PersistenceXmlDescriptorBuildItem> persistenceXmlDescriptors,
BuildProducer<NativeImageResourceBuildItem> resourceProducer,
ApplicationArchivesBuildItem applicationArchivesBuildItem,
LaunchModeBuildItem launchMode,
JpaEntitiesBuildItem domainObjects,
List<NonJpaModelBuildItem> nonJpaModelBuildItems,
BuildProducer<SystemPropertyBuildItem> systemPropertyProducer,
BuildProducer<PersistenceUnitDescriptorBuildItem> persistenceUnitDescriptorProducer) {
final boolean enableHR = hasEntities(domainObjects, nonJpaModelBuildItems);
if (!enableHR) {
// we have to bail out early as we might not have a Vertx pool configuration
return;
}
// Block any reactive persistence units from using persistence.xml
for (PersistenceXmlDescriptorBuildItem persistenceXmlDescriptorBuildItem : persistenceXmlDescriptors) {
String provider = persistenceXmlDescriptorBuildItem.getDescriptor().getProviderClassName();
if (provider == null ||
provider.equals(FastBootHibernateReactivePersistenceProvider.class.getCanonicalName()) ||
provider.equals(FastBootHibernateReactivePersistenceProvider.IMPLEMENTATION_NAME)) {
throw new ConfigurationError(
"Cannot use persistence.xml with Hibernate Reactive in Quarkus. Must use application.properties instead.");
}
}
// we only support the default pool for now
Optional<String> dbKind = dataSourcesBuildTimeConfig.defaultDataSource.dbKind;
ParsedPersistenceXmlDescriptor reactivePU = generateReactivePersistenceUnit(resourceProducer, systemPropertyProducer,
dbKind, applicationArchivesBuildItem, launchMode.getLaunchMode());
persistenceUnitDescriptorProducer.produce(new PersistenceUnitDescriptorBuildItem(reactivePU));
}
/**
* Returns the {@link ParsedPersistenceXmlDescriptor} instance constructed from persistence.xml.
*/
public static ParsedPersistenceXmlDescriptor getParsedPersistenceXmlDescriptor() {
return PersistenceXmlParser.locatePersistenceUnits(new Properties()).stream()
.filter(unit -> PersistenceModule.PERSISTENCE_UNIT_NAME.equals(unit.getName()))
.findFirst()
.orElseThrow(
() ->
new IllegalArgumentException(
String.format(
"Could not find persistence unit with name %s",
PersistenceModule.PERSISTENCE_UNIT_NAME)));
}
/** Constructs the {@link EntityManagerFactory} instance. */
private EntityManagerFactory createEntityManagerFactory(
String jdbcUrl,
String username,
String password,
ImmutableMap<String, String> configs,
ImmutableList<Class> extraEntityClasses) {
HashMap<String, String> properties = Maps.newHashMap(configs);
properties.put(Environment.URL, jdbcUrl);
properties.put(Environment.USER, username);
properties.put(Environment.PASS, password);
// Tell Postgresql JDBC driver to expect out-of-band schema change.
properties.put("hibernate.hikari.dataSource.autosave", "conservative");
ParsedPersistenceXmlDescriptor descriptor =
PersistenceXmlUtility.getParsedPersistenceXmlDescriptor();
// If we don't include the nomulus schema, remove all entity classes in the descriptor but keep
// other settings like the converter classes.
if (!includeNomulusSchema) {
List<String> nonEntityClasses =
descriptor.getManagedClassNames().stream()
.filter(
classString -> {
try {
return !Class.forName(classString).isAnnotationPresent(Entity.class);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException(e);
}
})
.collect(toImmutableList());
descriptor.getManagedClassNames().clear();
descriptor.getManagedClassNames().addAll(nonEntityClasses);
}
extraEntityClasses.stream().map(Class::getName).forEach(descriptor::addClasses);
return Bootstrap.getEntityManagerFactoryBuilder(descriptor, properties).build();
}
@Record(ExecutionTime.STATIC_INIT)
@BuildStep
void configureHibernate(KeycloakRecorder recorder, List<PersistenceUnitDescriptorBuildItem> descriptors) {
// TODO: ORM extension is going to provide build items that we can rely on to create our own PU instead of relying
// on the parsed descriptor and assume that the order that build steps are executed is always the same (although dialect
// is only created during runtime)
ParsedPersistenceXmlDescriptor unit = descriptors.get(0).getDescriptor();
unit.setTransactionType(PersistenceUnitTransactionType.JTA);
unit.getProperties().setProperty(AvailableSettings.DIALECT, DelegatingDialect.class.getName());
unit.getProperties().setProperty(AvailableSettings.QUERY_STARTUP_CHECKING, Boolean.FALSE.toString());
}
protected EntityManagerFactoryBuilder getEntityManagerFactoryBuilderOrNull(String persistenceUnitName, Map properties) {
log.tracef( "Attempting to obtain correct EntityManagerFactoryBuilder for persistenceUnitName : %s", persistenceUnitName );
final List<ParsedPersistenceXmlDescriptor> units;
try {
units = PersistenceXmlParser.locatePersistenceUnits( properties );
}
catch (Exception e) {
log.debug( "Unable to locate persistence units", e );
throw new PersistenceException( "Unable to locate persistence units", e );
}
log.debugf( "Located and parsed %s persistence units; checking each", units.size() );
if ( persistenceUnitName == null && units.size() > 1 ) {
// no persistence-unit name to look for was given and we found multiple persistence-units
throw new PersistenceException( "No name provided and multiple persistence units found" );
}
for ( ParsedPersistenceXmlDescriptor persistenceUnit : units ) {
log.debugf(
"Checking persistence-unit [name=%s, explicit-provider=%s] against incoming persistence unit name [%s]",
persistenceUnit.getName(),
persistenceUnit.getProviderClassName(),
persistenceUnitName
);
final boolean matches = persistenceUnitName == null || persistenceUnit.getName().equals( persistenceUnitName );
if ( !matches ) {
log.debug( "Excluding from consideration due to name mis-match" );
continue;
}
// See if we (Hibernate Reactive) are the persistence provider
if ( ! ReactiveProviderChecker.isProvider( persistenceUnit, properties ) ) {
log.debug( "Excluding from consideration due to provider mis-match" );
continue;
}
return getEntityManagerFactoryBuilder( persistenceUnit, properties );
}
log.debug( "Found no matching persistence units" );
return null;
}
@BuildStep
public void configurationDescriptorBuilding(
List<JdbcDataSourceBuildItem> jdbcDataSourcesBuildItem,
List<PersistenceXmlDescriptorBuildItem> persistenceXmlDescriptors,
BuildProducer<NativeImageResourceBuildItem> resourceProducer,
Capabilities capabilities,
ApplicationArchivesBuildItem applicationArchivesBuildItem,
LaunchModeBuildItem launchMode,
JpaEntitiesBuildItem domainObjects,
List<NonJpaModelBuildItem> nonJpaModelBuildItems,
BuildProducer<SystemPropertyBuildItem> systemPropertyProducer,
BuildProducer<PersistenceUnitDescriptorBuildItem> persistenceUnitDescriptorProducer) {
final boolean enableORM = hasEntities(domainObjects, nonJpaModelBuildItems);
if (!enableORM) {
// we have to bail out early as we might not have a datasource configuration
return;
}
// we only support the default datasource for now
Optional<JdbcDataSourceBuildItem> defaultJdbcDataSourceBuildItem = jdbcDataSourcesBuildItem.stream()
.filter(i -> i.isDefault())
.findFirst();
// handle the implicit persistence unit
List<ParsedPersistenceXmlDescriptor> allDescriptors = new ArrayList<>(persistenceXmlDescriptors.size() + 1);
for (PersistenceXmlDescriptorBuildItem persistenceXmlDescriptorBuildItem : persistenceXmlDescriptors) {
allDescriptors.add(persistenceXmlDescriptorBuildItem.getDescriptor());
}
final boolean hibernateReactivePresent = capabilities.isPresent(Capability.HIBERNATE_REACTIVE);
if (!hibernateReactivePresent) {
handleHibernateORMWithNoPersistenceXml(allDescriptors, resourceProducer, systemPropertyProducer,
defaultJdbcDataSourceBuildItem, applicationArchivesBuildItem, launchMode.getLaunchMode());
}
for (ParsedPersistenceXmlDescriptor descriptor : allDescriptors) {
persistenceUnitDescriptorProducer.produce(new PersistenceUnitDescriptorBuildItem(descriptor));
}
}
@SuppressWarnings("unchecked")
@BuildStep
@Record(STATIC_INIT)
public void build(RecorderContext recorderContext, HibernateOrmRecorder recorder,
Capabilities capabilities,
JpaEntitiesBuildItem domainObjects,
List<NonJpaModelBuildItem> nonJpaModelBuildItems,
List<PersistenceUnitDescriptorBuildItem> persistenceUnitDescriptorBuildItems,
List<HibernateOrmIntegrationBuildItem> integrations, //Used to make sure ORM integrations are performed before this item
ProxyDefinitionsBuildItem proxyDefinitions,
BuildProducer<FeatureBuildItem> feature,
BuildProducer<BeanContainerListenerBuildItem> beanContainerListener) throws Exception {
feature.produce(new FeatureBuildItem(Feature.HIBERNATE_ORM));
final boolean enableORM = hasEntities(domainObjects, nonJpaModelBuildItems);
final boolean hibernateReactivePresent = capabilities.isPresent(Capability.HIBERNATE_REACTIVE);
//The Hibernate Reactive extension is able to handle registration of PersistenceProviders for both reactive and
//traditional blocking Hibernate, by depending on this module and delegating to this code.
//So when the Hibernate Reactive extension is present, trust that it will register its own PersistenceProvider
//which will be responsible to decide which type of ORM to bootstrap.
//But if the extension is not present, we need to register our own PersistenceProvider - even if the ORM is not enabled!
if (!hibernateReactivePresent) {
recorder.callHibernateFeatureInit(enableORM);
}
if (!enableORM) {
// we can bail out early
return;
}
recorder.enlistPersistenceUnit(domainObjects.getEntityClassNames());
final QuarkusScanner scanner = buildQuarkusScanner(domainObjects);
//now we serialize the XML and class list to bytecode, to remove the need to re-parse the XML on JVM startup
recorderContext.registerNonDefaultConstructor(ParsedPersistenceXmlDescriptor.class.getDeclaredConstructor(URL.class),
(i) -> Collections.singletonList(i.getPersistenceUnitRootUrl()));
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// inspect service files for additional integrators
Collection<Class<? extends Integrator>> integratorClasses = new LinkedHashSet<>();
for (String integratorClassName : ServiceUtil.classNamesNamedIn(classLoader, INTEGRATOR_SERVICE_FILE)) {
integratorClasses.add((Class<? extends Integrator>) recorderContext.classProxy(integratorClassName));
}
List<ParsedPersistenceXmlDescriptor> allDescriptors = new ArrayList<>();
for (PersistenceUnitDescriptorBuildItem pud : persistenceUnitDescriptorBuildItems) {
allDescriptors.add(pud.getDescriptor());
}
beanContainerListener
.produce(new BeanContainerListenerBuildItem(
recorder.initMetadata(allDescriptors, scanner, integratorClasses,
proxyDefinitions.getProxies(), getMultiTenancyStrategy())));
}
public PersistenceUnitDescriptorBuildItem(ParsedPersistenceXmlDescriptor descriptor) {
this.descriptor = descriptor;
}
public ParsedPersistenceXmlDescriptor getDescriptor() {
return descriptor;
}
public PersistenceXmlDescriptorBuildItem(ParsedPersistenceXmlDescriptor descriptor) {
this.descriptor = descriptor;
}
public ParsedPersistenceXmlDescriptor getDescriptor() {
return descriptor;
}
private EntityManagerFactoryBuilder getEntityManagerFactoryBuilderOrNull(String persistenceUnitName, Map properties,
ClassLoader providedClassLoader, ClassLoaderService providedClassLoaderService) {
log.tracef( "Attempting to obtain correct EntityManagerFactoryBuilder for persistenceUnitName : %s", persistenceUnitName );
final Map integration = wrap( properties );
final List<ParsedPersistenceXmlDescriptor> units;
try {
units = PersistenceXmlParser.locatePersistenceUnits( integration );
}
catch (Exception e) {
log.debug( "Unable to locate persistence units", e );
throw new PersistenceException( "Unable to locate persistence units", e );
}
log.debugf( "Located and parsed %s persistence units; checking each", units.size() );
if ( persistenceUnitName == null && units.size() > 1 ) {
// no persistence-unit name to look for was given and we found multiple persistence-units
throw new PersistenceException( "No name provided and multiple persistence units found" );
}
for ( ParsedPersistenceXmlDescriptor persistenceUnit : units ) {
log.debugf(
"Checking persistence-unit [name=%s, explicit-provider=%s] against incoming persistence unit name [%s]",
persistenceUnit.getName(),
persistenceUnit.getProviderClassName(),
persistenceUnitName
);
final boolean matches = persistenceUnitName == null || persistenceUnit.getName().equals( persistenceUnitName );
if ( !matches ) {
log.debug( "Excluding from consideration due to name mis-match" );
continue;
}
// See if we (Hibernate) are the persistence provider
if ( ! ProviderChecker.isProvider( persistenceUnit, properties ) ) {
log.debug( "Excluding from consideration due to provider mis-match" );
continue;
}
if (providedClassLoaderService != null) {
return getEntityManagerFactoryBuilder( persistenceUnit, integration, providedClassLoaderService );
}
else {
return getEntityManagerFactoryBuilder( persistenceUnit, integration, providedClassLoader );
}
}
log.debug( "Found no matching persistence units" );
return null;
}
/**
* Initialize JPA for use in Quarkus. In a native image. This must be called
* from within a static init method.
*
* In general the <code>parsedPersistenceXmlDescriptors</code> will be provided
* by calling {@link #loadOriginalXMLParsedDescriptors()} In Quarkus this is
* done in Quarkus's JPA ResourceProcessor.
*
* The scanner may be null to use the default scanner, or a custom scanner can be
* used to stop Hibernate scanning. It is expected that the scanner will be
* provided by Quarkus via its hold of Jandex info.
*
* @param parsedPersistenceXmlDescriptors
* @param scanner
*/
static void initializeJpa(List<ParsedPersistenceXmlDescriptor> parsedPersistenceXmlDescriptors,
Scanner scanner, Collection<Class<? extends Integrator>> additionalIntegrators,
PreGeneratedProxies preGeneratedProxies, MultiTenancyStrategy strategy) {
final List<PersistenceUnitDescriptor> units = convertPersistenceUnits(parsedPersistenceXmlDescriptors);
final Map<String, RecordedState> metadata = constructMetadataAdvance(units, scanner, additionalIntegrators,
preGeneratedProxies, strategy);
persistenceUnits = new PersistenceUnits(units, metadata);
}
/**
* Similar to {@link PersistenceXmlParser#locatePersistenceUnits(Map)}
* except it doesn't need a properties map, and avoids complaining if no resources are found.
*
* @return the list of ParsedPersistenceXmlDescriptor(s), after discovery and parsing.
*/
public static List<ParsedPersistenceXmlDescriptor> locatePersistenceUnits() {
final QuarkusPersistenceXmlParser parser = new QuarkusPersistenceXmlParser();
parser.doResolve();
return parser.getResolvedPersistenceUnits();
}