Skip to content

Instantly share code, notes, and snippets.

@gbadner
Created December 19, 2013 19:48
Show Gist options
  • Save gbadner/8045073 to your computer and use it in GitHub Desktop.
Save gbadner/8045073 to your computer and use it in GitHub Desktop.
EntityManagerFactoryBuilderImpl
public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuilder {
private static final EntityManagerMessageLogger LOG = Logger.getMessageLogger(
EntityManagerMessageLogger.class,
EntityManagerFactoryBuilderImpl.class.getName()
);
private static final String META_INF_ORM_XML = "META-INF/orm.xml";
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// New settings
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Names a {@link IntegratorProvider}
*/
public static final String INTEGRATOR_PROVIDER = "hibernate.integrator_provider";
/**
* Names a {@link StrategyRegistrationProviderList}
*/
public static final String STRATEGY_REGISTRATION_PROVIDERS = "hibernate.strategy_registration_provider";
/**
* Names a {@link TypeContributorList}
*/
public static final String TYPE_CONTRIBUTORS = "hibernate.type_contributors";
/**
* Names a Jandex {@link Index} instance to use.
*/
public static final String JANDEX_INDEX = "hibernate.jandex_index";
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Explicit "injectables"
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private Object validatorFactory;
private DataSource dataSource;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private final PersistenceUnitDescriptor persistenceUnit;
private final SettingsImpl settings = new SettingsImpl();
private final StandardServiceRegistryBuilder serviceRegistryBuilder;
private final Map configurationValues;
private final List<GrantedPermission> grantedJaccPermissions = new ArrayList<GrantedPermission>();
private final List<CacheRegionDefinition> cacheRegionDefinitions = new ArrayList<CacheRegionDefinition>();
// todo : would much prefer this as a local variable...
private final List<JaxbMapping> cfgXmlNamedMappings = new ArrayList<JaxbMapping>();
private Interceptor sessionFactoryInterceptor;
private NamingStrategy namingStrategy;
private SessionFactoryObserver suppliedSessionFactoryObserver;
private MetadataSources metadataSources;
private Configuration hibernateConfiguration;
private static EntityNotFoundDelegate jpaEntityNotFoundDelegate = new JpaEntityNotFoundDelegate();
private ClassLoader providedClassLoader;
private static class JpaEntityNotFoundDelegate implements EntityNotFoundDelegate, Serializable {
public void handleEntityNotFound(String entityName, Serializable id) {
throw new EntityNotFoundException( "Unable to find " + entityName + " with id " + id );
}
}
public EntityManagerFactoryBuilderImpl(PersistenceUnitDescriptor persistenceUnit, Map integrationSettings) {
this( persistenceUnit, integrationSettings, null );
}
public EntityManagerFactoryBuilderImpl(
PersistenceUnitDescriptor persistenceUnit,
Map integrationSettings,
ClassLoader providedClassLoader ) {
LogHelper.logPersistenceUnitInformation( persistenceUnit );
this.persistenceUnit = persistenceUnit;
if ( integrationSettings == null ) {
integrationSettings = Collections.emptyMap();
}
this.providedClassLoader = providedClassLoader;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// First we build the boot-strap service registry, which mainly handles class loader interactions
final BootstrapServiceRegistry bootstrapServiceRegistry = buildBootstrapServiceRegistry( persistenceUnit, integrationSettings );
// And the main service registry. This is needed to start adding configuration values, etc
this.serviceRegistryBuilder = new StandardServiceRegistryBuilder( bootstrapServiceRegistry );
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Next we build a merged map of all the configuration values
this.configurationValues = mergePropertySources( persistenceUnit, integrationSettings, bootstrapServiceRegistry );
// add all merged configuration values into the service registry builder
this.serviceRegistryBuilder.applySettings( configurationValues );
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Next we do a preliminary pass at metadata processing, which involves:
// 1) scanning
final ScanResult scanResult = scan( bootstrapServiceRegistry );
final DeploymentResources deploymentResources = buildDeploymentResources( scanResult, bootstrapServiceRegistry );
// 2) building a Jandex index
final IndexView jandexIndex = locateOrBuildJandexIndex( deploymentResources );
// 3) building "metadata sources" to keep for later to use in building the SessionFactory
metadataSources = prepareMetadataSources( jandexIndex, deploymentResources, bootstrapServiceRegistry );
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
withValidatorFactory( configurationValues.get( AvailableSettings.VALIDATION_FACTORY ) );
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// push back class transformation to the environment; for the time being this only has any effect in EE
// container situations, calling back into PersistenceUnitInfo#addClassTransformer
final boolean useClassTransformer = "true".equals( configurationValues.remove( AvailableSettings.USE_CLASS_ENHANCER ) );
if ( useClassTransformer ) {
persistenceUnit.pushClassTransformer( metadataSources.collectMappingClassNames() );
}
}
<<<<<<< HEAD
private static interface DeploymentResources {
public Iterable<ClassDescriptor> getClassDescriptors();
public Iterable<PackageDescriptor> getPackageDescriptors();
public Iterable<MappingFileDescriptor> getMappingFileDescriptors();
}
private DeploymentResources buildDeploymentResources(
ScanResult scanResult,
BootstrapServiceRegistry bootstrapServiceRegistry) {
// mapping files ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
final ArrayList<MappingFileDescriptor> mappingFileDescriptors = new ArrayList<MappingFileDescriptor>();
final Set<String> nonLocatedMappingFileNames = new HashSet<String>();
final List<String> explicitMappingFileNames = persistenceUnit.getMappingFileNames();
if ( explicitMappingFileNames != null ) {
nonLocatedMappingFileNames.addAll( explicitMappingFileNames );
}
for ( MappingFileDescriptor mappingFileDescriptor : scanResult.getLocatedMappingFiles() ) {
mappingFileDescriptors.add( mappingFileDescriptor );
nonLocatedMappingFileNames.remove( mappingFileDescriptor.getName() );
}
for ( String name : nonLocatedMappingFileNames ) {
MappingFileDescriptor descriptor = buildMappingFileDescriptor( name, bootstrapServiceRegistry );
mappingFileDescriptors.add( descriptor );
}
// classes and packages ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
final HashMap<String, ClassDescriptor> classDescriptorMap = new HashMap<String, ClassDescriptor>();
final HashMap<String, PackageDescriptor> packageDescriptorMap = new HashMap<String, PackageDescriptor>();
for ( ClassDescriptor classDescriptor : scanResult.getLocatedClasses() ) {
classDescriptorMap.put( classDescriptor.getName(), classDescriptor );
}
for ( PackageDescriptor packageDescriptor : scanResult.getLocatedPackages() ) {
packageDescriptorMap.put( packageDescriptor.getName(), packageDescriptor );
}
final List<String> explicitClassNames = persistenceUnit.getManagedClassNames();
if ( explicitClassNames != null ) {
for ( String explicitClassName : explicitClassNames ) {
// IMPL NOTE : explicitClassNames can contain class or package names!!!
if ( classDescriptorMap.containsKey( explicitClassName ) ) {
continue;
}
if ( packageDescriptorMap.containsKey( explicitClassName ) ) {
continue;
}
// try it as a class name first...
final String classFileName = explicitClassName.replace( '.', '/' ) + ".class";
final URL classFileUrl = bootstrapServiceRegistry.getService( ClassLoaderService.class )
.locateResource( classFileName );
if ( classFileUrl != null ) {
classDescriptorMap.put(
explicitClassName,
new ClassDescriptorImpl( explicitClassName, new UrlInputStreamAccess( classFileUrl ) )
);
continue;
}
// otherwise, try it as a package name
final String packageInfoFileName = explicitClassName.replace( '.', '/' ) + "/package-info.class";
final URL packageInfoFileUrl = bootstrapServiceRegistry.getService( ClassLoaderService.class )
.locateResource( packageInfoFileName );
if ( packageInfoFileUrl != null ) {
packageDescriptorMap.put(
explicitClassName,
new PackageDescriptorImpl( explicitClassName, new UrlInputStreamAccess( packageInfoFileUrl ) )
);
continue;
}
LOG.debugf(
"Unable to resolve class [%s] named in persistence unit [%s]",
explicitClassName,
persistenceUnit.getName()
);
}
}
return new DeploymentResources() {
@Override
public Iterable<ClassDescriptor> getClassDescriptors() {
return classDescriptorMap.values();
}
@Override
public Iterable<PackageDescriptor> getPackageDescriptors() {
return packageDescriptorMap.values();
}
@Override
public Iterable<MappingFileDescriptor> getMappingFileDescriptors() {
return mappingFileDescriptors;
}
};
}
private MappingFileDescriptor buildMappingFileDescriptor(
String name,
BootstrapServiceRegistry bootstrapServiceRegistry) {
final URL url = bootstrapServiceRegistry.getService( ClassLoaderService.class ).locateResource( name );
if ( url == null ) {
throw persistenceException( "Unable to resolve named mapping-file [" + name + "]" );
}
return new MappingFileDescriptorImpl( name, new UrlInputStreamAccess( url ) );
=======
@SuppressWarnings("unchecked")
private Map mergePropertySources(
PersistenceUnitDescriptor persistenceUnit,
Map integrationSettings,
final BootstrapServiceRegistry bootstrapServiceRegistry) {
JpaUnifiedSettingsBuilder.Result mergedResult = JpaUnifiedSettingsBuilder.mergePropertySources(
persistenceUnit,
integrationSettings,
bootstrapServiceRegistry
);
cfgXmlNamedMappings.addAll( mergedResult.getCfgXmlMappingArtifacts().getMappings() );
cacheRegionDefinitions.addAll( mergedResult.getCfgXmlMappingArtifacts().getCacheRegionDefinitions() );
jaccDefinitions.addAll( mergedResult.getCfgXmlMappingArtifacts().getJaccDefinitions() );
return mergedResult.getSettings();
>>>>>>> HHH-6159 - Create EntityManagerFactoryBuilder : integrate EntityManagerFactoryBuilder with metamodel codebase
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// temporary!
@SuppressWarnings("unchecked")
public Map getConfigurationValues() {
return Collections.unmodifiableMap( configurationValues );
}
public Configuration getHibernateConfiguration() {
return hibernateConfiguration;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@SuppressWarnings("unchecked")
private MetadataSources prepareMetadataSources(
IndexView jandexIndex,
DeploymentResources deploymentResources,
BootstrapServiceRegistry bootstrapServiceRegistry) {
// todo : this needs to tie into the metamodel branch...
MetadataSources metadataSources = new MetadataSources();
for ( ClassDescriptor classDescriptor : deploymentResources.getClassDescriptors() ) {
final String className = classDescriptor.getName();
final ClassInfo classInfo = jandexIndex.getClassByName( DotName.createSimple( className ) );
if ( classInfo == null ) {
// Not really sure what this means. Most likely it is explicitly listed in the persistence unit,
// but mapped via mapping file. Anyway assume its a mapping class...
metadataSources.annotatedMappingClassNames.add( className );
continue;
}
// logic here assumes an entity is not also a converter...
AnnotationInstance converterAnnotation = JandexHelper.getSingleAnnotation(
classInfo.annotations(),
JPADotNames.CONVERTER
);
if ( converterAnnotation != null ) {
metadataSources.converterDescriptors.add(
new MetadataSources.ConverterDescriptor(
className,
JandexHelper.getValue( converterAnnotation, "autoApply", boolean.class,
bootstrapServiceRegistry.getService( ClassLoaderService.class ) )
)
);
}
else {
metadataSources.annotatedMappingClassNames.add( className );
}
}
for ( PackageDescriptor packageDescriptor : deploymentResources.getPackageDescriptors() ) {
metadataSources.packageNames.add( packageDescriptor.getName() );
}
for ( MappingFileDescriptor mappingFileDescriptor : deploymentResources.getMappingFileDescriptors() ) {
metadataSources.namedMappingFileInputStreams.add( mappingFileDescriptor.getStreamAccess().asNamedInputStream() );
}
final String explicitHbmXmls = (String) configurationValues.remove( AvailableSettings.HBXML_FILES );
if ( explicitHbmXmls != null ) {
metadataSources.mappingFileResources.addAll( Arrays.asList( StringHelper.split( ", ", explicitHbmXmls ) ) );
}
final List<String> explicitOrmXml = (List<String>) configurationValues.remove( AvailableSettings.XML_FILE_NAMES );
if ( explicitOrmXml != null ) {
metadataSources.mappingFileResources.addAll( explicitOrmXml );
}
return metadataSources;
}
private IndexView locateOrBuildJandexIndex(DeploymentResources deploymentResources) {
// for now create a whole new Index to work with, eventually we need to:
// 1) accept an Index as an incoming config value
// 2) pass that Index along to the metamodel code...
IndexView jandexIndex = (IndexView) configurationValues.get( JANDEX_INDEX );
if ( jandexIndex == null ) {
jandexIndex = buildJandexIndex( deploymentResources );
}
return jandexIndex;
}
private IndexView buildJandexIndex(DeploymentResources deploymentResources) {
Indexer indexer = new Indexer();
for ( ClassDescriptor classDescriptor : deploymentResources.getClassDescriptors() ) {
indexStream( indexer, classDescriptor.getStreamAccess() );
}
for ( PackageDescriptor packageDescriptor : deploymentResources.getPackageDescriptors() ) {
indexStream( indexer, packageDescriptor.getStreamAccess() );
}
// for now we just skip entities defined in (1) orm.xml files and (2) hbm.xml files. this part really needs
// metamodel branch...
// for now, we also need to wrap this in a CompositeIndex until Jandex is updated to use a common interface
// between the 2...
return indexer.complete();
}
<<<<<<< HEAD
private void indexStream(Indexer indexer, InputStreamAccess streamAccess) {
=======
private void indexResource(String resourceName, Indexer indexer, BootstrapServiceRegistry bootstrapServiceRegistry) {
InputStream stream = bootstrapServiceRegistry.getService( ClassLoaderService.class ).locateResourceStream(
resourceName
);
>>>>>>> HHH-6159 - Create EntityManagerFactoryBuilder : integrate EntityManagerFactoryBuilder with metamodel codebase
try {
InputStream stream = streamAccess.accessInputStream();
try {
indexer.index( stream );
}
finally {
try {
stream.close();
}
catch (Exception ignore) {
}
}
}
catch ( IOException e ) {
throw persistenceException( "Unable to index from stream " + streamAccess.getStreamName(), e );
}
}
<<<<<<< HEAD
/**
* Builds the {@link BootstrapServiceRegistry} used to eventually build the {@link org.hibernate.boot.registry.StandardServiceRegistryBuilder}; mainly
* used here during instantiation to define class-loading behavior.
*
* @param integrationSettings Any integration settings passed by the EE container or SE application
*
* @return The built BootstrapServiceRegistry
*/
private BootstrapServiceRegistry buildBootstrapServiceRegistry(Map integrationSettings) {
final BootstrapServiceRegistryBuilder bootstrapServiceRegistryBuilder = new BootstrapServiceRegistryBuilder();
bootstrapServiceRegistryBuilder.with( new JpaIntegrator() );
final IntegratorProvider integratorProvider = (IntegratorProvider) integrationSettings.get( INTEGRATOR_PROVIDER );
if ( integratorProvider != null ) {
for ( Integrator integrator : integratorProvider.getIntegrators() ) {
bootstrapServiceRegistryBuilder.with( integrator );
}
}
final StrategyRegistrationProviderList strategyRegistrationProviderList
= (StrategyRegistrationProviderList) integrationSettings.get( STRATEGY_REGISTRATION_PROVIDERS );
if ( strategyRegistrationProviderList != null ) {
for ( StrategyRegistrationProvider strategyRegistrationProvider : strategyRegistrationProviderList
.getStrategyRegistrationProviders() ) {
bootstrapServiceRegistryBuilder.withStrategySelectors( strategyRegistrationProvider );
}
}
// TODO: If providedClassLoader is present (OSGi, etc.) *and*
// an APP_CLASSLOADER is provided, should throw an exception or
// warn?
ClassLoader classLoader;
ClassLoader appClassLoader = (ClassLoader) integrationSettings.get( org.hibernate.cfg.AvailableSettings.APP_CLASSLOADER );
if ( providedClassLoader != null ) {
classLoader = providedClassLoader;
}
else if ( appClassLoader != null ) {
classLoader = appClassLoader;
}
else {
classLoader = persistenceUnit.getClassLoader();
}
bootstrapServiceRegistryBuilder.with( classLoader );
return bootstrapServiceRegistryBuilder.build();
}
@SuppressWarnings("unchecked")
private Map mergePropertySources(
PersistenceUnitDescriptor persistenceUnit,
Map integrationSettings,
final BootstrapServiceRegistry bootstrapServiceRegistry) {
final Map merged = new HashMap();
// first, apply persistence.xml-defined settings
if ( persistenceUnit.getProperties() != null ) {
merged.putAll( persistenceUnit.getProperties() );
}
merged.put( AvailableSettings.PERSISTENCE_UNIT_NAME, persistenceUnit.getName() );
// see if the persistence.xml settings named a Hibernate config file....
final ValueHolder<ConfigLoader> configLoaderHolder = new ValueHolder<ConfigLoader>(
new ValueHolder.DeferredInitializer<ConfigLoader>() {
@Override
public ConfigLoader initialize() {
return new ConfigLoader( bootstrapServiceRegistry );
}
}
);
final String cfgXmlResourceName1 = (String) merged.remove( AvailableSettings.CFG_FILE );
if ( StringHelper.isNotEmpty( cfgXmlResourceName1 ) ) {
// it does, so load those properties
JaxbHibernateConfiguration configurationElement = configLoaderHolder.getValue()
.loadConfigXmlResource( cfgXmlResourceName1 );
processHibernateConfigurationElement( configurationElement, merged );
}
// see if integration settings named a Hibernate config file....
final String cfgXmlResourceName2 = (String) integrationSettings.get( AvailableSettings.CFG_FILE );
if ( StringHelper.isNotEmpty( cfgXmlResourceName2 ) ) {
integrationSettings.remove( AvailableSettings.CFG_FILE );
// it does, so load those properties
JaxbHibernateConfiguration configurationElement = configLoaderHolder.getValue().loadConfigXmlResource(
cfgXmlResourceName2
);
processHibernateConfigurationElement( configurationElement, merged );
}
// finally, apply integration-supplied settings (per JPA spec, integration settings should override other sources)
merged.putAll( integrationSettings );
if ( !merged.containsKey( AvailableSettings.VALIDATION_MODE ) ) {
if ( persistenceUnit.getValidationMode() != null ) {
merged.put( AvailableSettings.VALIDATION_MODE, persistenceUnit.getValidationMode() );
}
}
if ( !merged.containsKey( AvailableSettings.SHARED_CACHE_MODE ) ) {
if ( persistenceUnit.getSharedCacheMode() != null ) {
merged.put( AvailableSettings.SHARED_CACHE_MODE, persistenceUnit.getSharedCacheMode() );
}
}
// was getting NPE exceptions from the underlying map when just using #putAll, so going this safer route...
Iterator itr = merged.entrySet().iterator();
while ( itr.hasNext() ) {
final Map.Entry entry = (Map.Entry) itr.next();
if ( entry.getValue() == null ) {
itr.remove();
}
}
return merged;
}
@SuppressWarnings("unchecked")
private void processHibernateConfigurationElement(
JaxbHibernateConfiguration configurationElement,
Map mergeMap) {
if ( ! mergeMap.containsKey( org.hibernate.cfg.AvailableSettings.SESSION_FACTORY_NAME ) ) {
String cfgName = configurationElement.getSessionFactory().getName();
if ( cfgName != null ) {
mergeMap.put( org.hibernate.cfg.AvailableSettings.SESSION_FACTORY_NAME, cfgName );
}
}
for ( JaxbHibernateConfiguration.JaxbSessionFactory.JaxbProperty jaxbProperty : configurationElement.getSessionFactory().getProperty() ) {
mergeMap.put( jaxbProperty.getName(), jaxbProperty.getValue() );
}
for ( JaxbHibernateConfiguration.JaxbSessionFactory.JaxbMapping jaxbMapping : configurationElement.getSessionFactory().getMapping() ) {
cfgXmlNamedMappings.add( jaxbMapping );
}
for ( Object cacheDeclaration : configurationElement.getSessionFactory().getClassCacheOrCollectionCache() ) {
if ( JaxbHibernateConfiguration.JaxbSessionFactory.JaxbClassCache.class.isInstance( cacheDeclaration ) ) {
final JaxbHibernateConfiguration.JaxbSessionFactory.JaxbClassCache jaxbClassCache
= (JaxbHibernateConfiguration.JaxbSessionFactory.JaxbClassCache) cacheDeclaration;
cacheRegionDefinitions.add(
new CacheRegionDefinition(
CacheRegionDefinition.CacheType.ENTITY,
jaxbClassCache.getClazz(),
jaxbClassCache.getUsage().value(),
jaxbClassCache.getRegion(),
"all".equals( jaxbClassCache.getInclude() )
)
);
}
else {
final JaxbHibernateConfiguration.JaxbSessionFactory.JaxbCollectionCache jaxbCollectionCache
= (JaxbHibernateConfiguration.JaxbSessionFactory.JaxbCollectionCache) cacheDeclaration;
cacheRegionDefinitions.add(
new CacheRegionDefinition(
CacheRegionDefinition.CacheType.COLLECTION,
jaxbCollectionCache.getCollection(),
jaxbCollectionCache.getUsage().value(),
jaxbCollectionCache.getRegion(),
false
)
);
}
}
if ( configurationElement.getSecurity() != null ) {
for ( JaxbHibernateConfiguration.JaxbSecurity.JaxbGrant grant : configurationElement.getSecurity().getGrant() ) {
grantedJaccPermissions.add(
new GrantedPermission(
grant.getRole(),
grant.getEntityName(),
grant.getActions()
)
);
=======
private void processProperties(BootstrapServiceRegistry bootstrapServiceRegistry) {
applyJdbcConnectionProperties();
applyTransactionProperties();
final Object validationFactory = configurationValues.get( AvailableSettings.VALIDATION_FACTORY );
if ( validationFactory != null ) {
BeanValidationIntegrator.validateFactory( validationFactory );
}
// flush before completion validation
if ( "true".equals( configurationValues.get( Environment.FLUSH_BEFORE_COMPLETION ) ) ) {
serviceRegistryBuilder.applySetting( Environment.FLUSH_BEFORE_COMPLETION, "false" );
LOG.definingFlushBeforeCompletionIgnoredInHem( Environment.FLUSH_BEFORE_COMPLETION );
}
for ( Map.Entry entry : configurationValues.entrySet() ) {
if ( entry.getKey() instanceof String ) {
final String keyString = (String) entry.getKey();
if ( AvailableSettings.INTERCEPTOR.equals( keyString ) ) {
sessionFactoryInterceptor = instantiateCustomClassFromConfiguration(
entry.getValue(),
Interceptor.class,
bootstrapServiceRegistry
);
}
else if ( AvailableSettings.SESSION_INTERCEPTOR.equals( keyString ) ) {
settings.setSessionInterceptorClass(
loadSessionInterceptorClass( entry.getValue(), bootstrapServiceRegistry )
);
}
else if ( AvailableSettings.NAMING_STRATEGY.equals( keyString ) ) {
namingStrategy = instantiateCustomClassFromConfiguration(
entry.getValue(),
NamingStrategy.class,
bootstrapServiceRegistry
);
}
else if ( AvailableSettings.SESSION_FACTORY_OBSERVER.equals( keyString ) ) {
suppliedSessionFactoryObserver = instantiateCustomClassFromConfiguration(
entry.getValue(),
SessionFactoryObserver.class,
bootstrapServiceRegistry
);
}
else if ( AvailableSettings.DISCARD_PC_ON_CLOSE.equals( keyString ) ) {
settings.setReleaseResourcesOnCloseEnabled( "true".equals( entry.getValue() ) );
}
else if ( keyString.startsWith( AvailableSettings.CLASS_CACHE_PREFIX ) ) {
addCacheRegionDefinition(
keyString.substring( AvailableSettings.CLASS_CACHE_PREFIX.length() + 1 ),
(String) entry.getValue(),
CacheRegionDefinition.CacheRegionType.ENTITY
);
}
else if ( keyString.startsWith( AvailableSettings.COLLECTION_CACHE_PREFIX ) ) {
addCacheRegionDefinition(
keyString.substring( AvailableSettings.COLLECTION_CACHE_PREFIX.length() + 1 ),
(String) entry.getValue(),
CacheRegionDefinition.CacheRegionType.COLLECTION
);
}
else if ( keyString.startsWith( AvailableSettings.JACC_PREFIX )
&& ! ( keyString.equals( AvailableSettings.JACC_CONTEXT_ID )
|| keyString.equals( AvailableSettings.JACC_ENABLED ) ) ) {
addJaccDefinition( (String) entry.getKey(), entry.getValue() );
}
}
}
}
private void applyJdbcConnectionProperties() {
if ( persistenceUnit.getJtaDataSource() != null ) {
serviceRegistryBuilder.applySetting( Environment.DATASOURCE, persistenceUnit.getJtaDataSource() );
}
else if ( persistenceUnit.getNonJtaDataSource() != null ) {
serviceRegistryBuilder.applySetting( Environment.DATASOURCE, persistenceUnit.getNonJtaDataSource() );
}
else {
final String driver = (String) configurationValues.get( AvailableSettings.JDBC_DRIVER );
if ( StringHelper.isNotEmpty( driver ) ) {
serviceRegistryBuilder.applySetting( org.hibernate.cfg.AvailableSettings.DRIVER, driver );
}
final String url = (String) configurationValues.get( AvailableSettings.JDBC_URL );
if ( StringHelper.isNotEmpty( url ) ) {
serviceRegistryBuilder.applySetting( org.hibernate.cfg.AvailableSettings.URL, url );
}
final String user = (String) configurationValues.get( AvailableSettings.JDBC_USER );
if ( StringHelper.isNotEmpty( user ) ) {
serviceRegistryBuilder.applySetting( org.hibernate.cfg.AvailableSettings.USER, user );
}
final String pass = (String) configurationValues.get( AvailableSettings.JDBC_PASSWORD );
if ( StringHelper.isNotEmpty( pass ) ) {
serviceRegistryBuilder.applySetting( org.hibernate.cfg.AvailableSettings.PASS, pass );
}
}
}
private void applyTransactionProperties() {
PersistenceUnitTransactionType txnType = PersistenceUnitTransactionTypeHelper.interpretTransactionType(
configurationValues.get( AvailableSettings.TRANSACTION_TYPE )
);
if ( txnType == null ) {
txnType = persistenceUnit.getTransactionType();
}
if ( txnType == null ) {
// is it more appropriate to have this be based on bootstrap entry point (EE vs SE)?
txnType = PersistenceUnitTransactionType.RESOURCE_LOCAL;
}
settings.setTransactionType( txnType );
boolean hasTxStrategy = configurationValues.containsKey( Environment.TRANSACTION_STRATEGY );
if ( hasTxStrategy ) {
LOG.overridingTransactionStrategyDangerous( Environment.TRANSACTION_STRATEGY );
}
else {
if ( txnType == PersistenceUnitTransactionType.JTA ) {
serviceRegistryBuilder.applySetting( Environment.TRANSACTION_STRATEGY, CMTTransactionFactory.class );
}
else if ( txnType == PersistenceUnitTransactionType.RESOURCE_LOCAL ) {
serviceRegistryBuilder.applySetting( Environment.TRANSACTION_STRATEGY, JdbcTransactionFactory.class );
>>>>>>> HHH-6159 - Create EntityManagerFactoryBuilder : integrate EntityManagerFactoryBuilder with metamodel codebase
}
}
}
private String jaccContextId;
private void addJaccDefinition(String key, Object value) {
if ( jaccContextId == null ) {
jaccContextId = (String) configurationValues.get( AvailableSettings.JACC_CONTEXT_ID );
if ( jaccContextId == null ) {
throw persistenceException(
"Entities have been configured for JACC, but "
+ AvailableSettings.JACC_CONTEXT_ID + " has not been set"
);
}
}
try {
final int roleStart = AvailableSettings.JACC_PREFIX.length() + 1;
final String role = key.substring( roleStart, key.indexOf( '.', roleStart ) );
final int classStart = roleStart + role.length() + 1;
final String clazz = key.substring( classStart, key.length() );
grantedJaccPermissions.add( new GrantedPermission( role, clazz, (String) value ) );
}
catch ( IndexOutOfBoundsException e ) {
throw persistenceException( "Illegal usage of " + AvailableSettings.JACC_PREFIX + ": " + key );
}
}
<<<<<<< HEAD
private void addCacheRegionDefinition(String role, String value, CacheRegionDefinition.CacheType cacheType) {
=======
@SuppressWarnings("unchecked")
private Class<? extends Interceptor> loadSessionInterceptorClass(
Object value,
BootstrapServiceRegistry bootstrapServiceRegistry) {
if ( value == null ) {
return null;
}
Class theClass;
if ( Class.class.isInstance( value ) ) {
theClass = (Class) value;
}
else {
theClass = bootstrapServiceRegistry.getService( ClassLoaderService.class ).classForName( value.toString() );
}
try {
return (Class<? extends Interceptor>) theClass;
}
catch (ClassCastException e) {
throw persistenceException(
String.format(
"Specified Interceptor implementation class [%s] was not castable to Interceptor",
theClass.getName()
)
);
}
}
private void addCacheRegionDefinition(String role, String value, CacheRegionDefinition.CacheRegionType cacheType) {
>>>>>>> HHH-6159 - Create EntityManagerFactoryBuilder : integrate EntityManagerFactoryBuilder with metamodel codebase
final StringTokenizer params = new StringTokenizer( value, ";, " );
if ( !params.hasMoreTokens() ) {
StringBuilder error = new StringBuilder( "Illegal usage of " );
if ( cacheType == CacheRegionDefinition.CacheRegionType.ENTITY ) {
error.append( AvailableSettings.CLASS_CACHE_PREFIX )
.append( ": " )
.append( AvailableSettings.CLASS_CACHE_PREFIX );
}
else {
error.append( AvailableSettings.COLLECTION_CACHE_PREFIX )
.append( ": " )
.append( AvailableSettings.COLLECTION_CACHE_PREFIX );
}
error.append( '.' )
.append( role )
.append( ' ' )
.append( value )
.append( ". Was expecting configuration, but found none" );
throw persistenceException( error.toString() );
}
String usage = params.nextToken();
String region = null;
if ( params.hasMoreTokens() ) {
region = params.nextToken();
}
boolean lazyProperty = true;
if ( cacheType == CacheRegionDefinition.CacheRegionType.ENTITY ) {
if ( params.hasMoreTokens() ) {
lazyProperty = "all".equalsIgnoreCase( params.nextToken() );
}
}
else {
lazyProperty = false;
}
final CacheRegionDefinition def = new CacheRegionDefinition( cacheType, role, usage, region, lazyProperty );
cacheRegionDefinitions.add( def );
}
@SuppressWarnings("unchecked")
private ScanResult scan(BootstrapServiceRegistry bootstrapServiceRegistry) {
final Scanner scanner = locateOrBuildScanner( bootstrapServiceRegistry );
final ScanOptions scanOptions = determineScanOptions();
return scanner.scan( persistenceUnit, scanOptions );
}
private ScanOptions determineScanOptions() {
return new StandardScanOptions(
(String) configurationValues.get( AvailableSettings.AUTODETECTION ),
persistenceUnit.isExcludeUnlistedClasses()
);
}
@SuppressWarnings("unchecked")
private Scanner locateOrBuildScanner(BootstrapServiceRegistry bootstrapServiceRegistry) {
final Object value = configurationValues.remove( AvailableSettings.SCANNER );
if ( value == null ) {
return new StandardScanner();
}
if ( Scanner.class.isInstance( value ) ) {
return (Scanner) value;
}
Class<? extends Scanner> scannerClass;
if ( Class.class.isInstance( value ) ) {
try {
scannerClass = (Class<? extends Scanner>) value;
}
catch ( ClassCastException e ) {
throw persistenceException( "Expecting Scanner implementation, but found " + ((Class) value).getName() );
}
}
else {
final String scannerClassName = value.toString();
try {
scannerClass = bootstrapServiceRegistry.getService( ClassLoaderService.class ).classForName( scannerClassName );
}
catch ( ClassCastException e ) {
throw persistenceException( "Expecting Scanner implementation, but found " + scannerClassName );
}
}
try {
return scannerClass.newInstance();
}
catch ( Exception e ) {
throw persistenceException( "Unable to instantiate Scanner class: " + scannerClass, e );
}
}
@Override
public EntityManagerFactoryBuilder withValidatorFactory(Object validatorFactory) {
this.validatorFactory = validatorFactory;
if ( validatorFactory != null ) {
BeanValidationIntegrator.validateFactory( validatorFactory );
}
return this;
}
@Override
public EntityManagerFactoryBuilder withDataSource(DataSource dataSource) {
this.dataSource = dataSource;
return this;
}
@Override
public void cancel() {
// todo : close the bootstrap registry (not critical, but nice to do)
}
@Override
public void generateSchema() {
processProperties();
final ServiceRegistry serviceRegistry = buildServiceRegistry();
final ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
// IMPL NOTE : TCCL handling here is temporary.
// It is needed because this code still uses Hibernate Configuration and Hibernate commons-annotations
// in turn which relies on TCCL being set.
( (ClassLoaderServiceImpl) classLoaderService ).withTccl(
new ClassLoaderServiceImpl.Work() {
@Override
public Object perform() {
final Configuration hibernateConfiguration = buildHibernateConfiguration( serviceRegistry );
// This seems overkill, but building the SF is necessary to get the Integrators to kick in.
// Metamodel will clean this up...
try {
hibernateConfiguration.buildSessionFactory( serviceRegistry );
}
catch (MappingException e) {
throw persistenceException( "Unable to build Hibernate SessionFactory", e );
}
JpaSchemaGenerator.performGeneration( hibernateConfiguration, serviceRegistry );
return null;
}
}
);
// release this builder
cancel();
}
@SuppressWarnings("unchecked")
public EntityManagerFactory build() {
processProperties();
final ServiceRegistry serviceRegistry = buildServiceRegistry();
final ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
// IMPL NOTE : TCCL handling here is temporary.
// It is needed because this code still uses Hibernate Configuration and Hibernate commons-annotations
// in turn which relies on TCCL being set.
return ( (ClassLoaderServiceImpl) classLoaderService ).withTccl(
new ClassLoaderServiceImpl.Work<EntityManagerFactoryImpl>() {
@Override
public EntityManagerFactoryImpl perform() {
hibernateConfiguration = buildHibernateConfiguration( serviceRegistry );
SessionFactoryImplementor sessionFactory;
try {
sessionFactory = (SessionFactoryImplementor) hibernateConfiguration.buildSessionFactory( serviceRegistry );
}
catch (MappingException e) {
throw persistenceException( "Unable to build Hibernate SessionFactory", e );
}
// must do after buildSessionFactory to let the Integrators kick in
JpaSchemaGenerator.performGeneration( hibernateConfiguration, serviceRegistry );
if ( suppliedSessionFactoryObserver != null ) {
sessionFactory.addObserver( suppliedSessionFactoryObserver );
}
sessionFactory.addObserver( new ServiceRegistryCloser() );
// NOTE : passing cfg is temporary until
return new EntityManagerFactoryImpl(
persistenceUnit.getName(),
sessionFactory,
settings,
configurationValues,
hibernateConfiguration
);
}
}
);
}
private void processProperties() {
applyJdbcConnectionProperties();
applyTransactionProperties();
Object validationFactory = this.validatorFactory;
if ( validationFactory == null ) {
validationFactory = configurationValues.get( AvailableSettings.VALIDATION_FACTORY );
}
if ( validationFactory != null ) {
BeanValidationIntegrator.validateFactory( validationFactory );
serviceRegistryBuilder.applySetting( AvailableSettings.VALIDATION_FACTORY, validationFactory );
configurationValues.put( AvailableSettings.VALIDATION_FACTORY, this.validatorFactory );
}
// flush before completion validation
if ( "true".equals( configurationValues.get( Environment.FLUSH_BEFORE_COMPLETION ) ) ) {
serviceRegistryBuilder.applySetting( Environment.FLUSH_BEFORE_COMPLETION, "false" );
LOG.definingFlushBeforeCompletionIgnoredInHem( Environment.FLUSH_BEFORE_COMPLETION );
}
final StrategySelector strategySelector = serviceRegistryBuilder.getBootstrapServiceRegistry().getService( StrategySelector.class );
for ( Object oEntry : configurationValues.entrySet() ) {
Map.Entry entry = (Map.Entry) oEntry;
if ( entry.getKey() instanceof String ) {
final String keyString = (String) entry.getKey();
if ( AvailableSettings.INTERCEPTOR.equals( keyString ) ) {
sessionFactoryInterceptor = strategySelector.resolveStrategy( Interceptor.class, entry.getValue() );
}
else if ( AvailableSettings.SESSION_INTERCEPTOR.equals( keyString ) ) {
settings.setSessionInterceptorClass(
loadSessionInterceptorClass( entry.getValue(), strategySelector )
);
}
else if ( AvailableSettings.NAMING_STRATEGY.equals( keyString ) ) {
namingStrategy = strategySelector.resolveStrategy( NamingStrategy.class, entry.getValue() );
}
else if ( AvailableSettings.SESSION_FACTORY_OBSERVER.equals( keyString ) ) {
suppliedSessionFactoryObserver = strategySelector.resolveStrategy( SessionFactoryObserver.class, entry.getValue() );
}
else if ( AvailableSettings.DISCARD_PC_ON_CLOSE.equals( keyString ) ) {
settings.setReleaseResourcesOnCloseEnabled( "true".equals( entry.getValue() ) );
}
else if ( keyString.startsWith( AvailableSettings.CLASS_CACHE_PREFIX ) ) {
addCacheRegionDefinition(
keyString.substring( AvailableSettings.CLASS_CACHE_PREFIX.length() + 1 ),
(String) entry.getValue(),
CacheRegionDefinition.CacheType.ENTITY
);
}
else if ( keyString.startsWith( AvailableSettings.COLLECTION_CACHE_PREFIX ) ) {
addCacheRegionDefinition(
keyString.substring( AvailableSettings.COLLECTION_CACHE_PREFIX.length() + 1 ),
(String) entry.getValue(),
CacheRegionDefinition.CacheType.COLLECTION
);
}
else if ( keyString.startsWith( AvailableSettings.JACC_PREFIX )
&& ! ( keyString.equals( AvailableSettings.JACC_CONTEXT_ID )
|| keyString.equals( AvailableSettings.JACC_ENABLED ) ) ) {
addJaccDefinition( (String) entry.getKey(), entry.getValue() );
}
}
}
}
private void applyJdbcConnectionProperties() {
if ( dataSource != null ) {
serviceRegistryBuilder.applySetting( org.hibernate.cfg.AvailableSettings.DATASOURCE, dataSource );
}
else if ( persistenceUnit.getJtaDataSource() != null ) {
if ( ! serviceRegistryBuilder.getSettings().containsKey( org.hibernate.cfg.AvailableSettings.DATASOURCE ) ) {
serviceRegistryBuilder.applySetting( org.hibernate.cfg.AvailableSettings.DATASOURCE, persistenceUnit.getJtaDataSource() );
// HHH-8121 : make the PU-defined value available to EMF.getProperties()
configurationValues.put( AvailableSettings.JTA_DATASOURCE, persistenceUnit.getJtaDataSource() );
}
}
else if ( persistenceUnit.getNonJtaDataSource() != null ) {
if ( ! serviceRegistryBuilder.getSettings().containsKey( org.hibernate.cfg.AvailableSettings.DATASOURCE ) ) {
serviceRegistryBuilder.applySetting( org.hibernate.cfg.AvailableSettings.DATASOURCE, persistenceUnit.getNonJtaDataSource() );
// HHH-8121 : make the PU-defined value available to EMF.getProperties()
configurationValues.put( AvailableSettings.NON_JTA_DATASOURCE, persistenceUnit.getNonJtaDataSource() );
}
}
else {
final String driver = (String) configurationValues.get( AvailableSettings.JDBC_DRIVER );
if ( StringHelper.isNotEmpty( driver ) ) {
serviceRegistryBuilder.applySetting( org.hibernate.cfg.AvailableSettings.DRIVER, driver );
}
final String url = (String) configurationValues.get( AvailableSettings.JDBC_URL );
if ( StringHelper.isNotEmpty( url ) ) {
serviceRegistryBuilder.applySetting( org.hibernate.cfg.AvailableSettings.URL, url );
}
final String user = (String) configurationValues.get( AvailableSettings.JDBC_USER );
if ( StringHelper.isNotEmpty( user ) ) {
serviceRegistryBuilder.applySetting( org.hibernate.cfg.AvailableSettings.USER, user );
}
final String pass = (String) configurationValues.get( AvailableSettings.JDBC_PASSWORD );
if ( StringHelper.isNotEmpty( pass ) ) {
serviceRegistryBuilder.applySetting( org.hibernate.cfg.AvailableSettings.PASS, pass );
}
}
}
private void applyTransactionProperties() {
PersistenceUnitTransactionType txnType = PersistenceUnitTransactionTypeHelper.interpretTransactionType(
configurationValues.get( AvailableSettings.TRANSACTION_TYPE )
);
if ( txnType == null ) {
txnType = persistenceUnit.getTransactionType();
}
if ( txnType == null ) {
// is it more appropriate to have this be based on bootstrap entry point (EE vs SE)?
txnType = PersistenceUnitTransactionType.RESOURCE_LOCAL;
}
settings.setTransactionType( txnType );
boolean hasTxStrategy = configurationValues.containsKey( Environment.TRANSACTION_STRATEGY );
if ( hasTxStrategy ) {
LOG.overridingTransactionStrategyDangerous( Environment.TRANSACTION_STRATEGY );
}
else {
if ( txnType == PersistenceUnitTransactionType.JTA ) {
serviceRegistryBuilder.applySetting( Environment.TRANSACTION_STRATEGY, CMTTransactionFactory.class );
}
else if ( txnType == PersistenceUnitTransactionType.RESOURCE_LOCAL ) {
serviceRegistryBuilder.applySetting( Environment.TRANSACTION_STRATEGY, JdbcTransactionFactory.class );
}
}
}
@SuppressWarnings("unchecked")
private Class<? extends Interceptor> loadSessionInterceptorClass(Object value, StrategySelector strategySelector) {
if ( value == null ) {
return null;
}
return Class.class.isInstance( value )
? (Class<? extends Interceptor>) value
: strategySelector.selectStrategyImplementor( Interceptor.class, value.toString() );
}
public ServiceRegistry buildServiceRegistry() {
return serviceRegistryBuilder.build();
}
public Configuration buildHibernateConfiguration(ServiceRegistry serviceRegistry) {
Properties props = new Properties();
props.putAll( configurationValues );
Configuration cfg = new Configuration();
cfg.getProperties().putAll( props );
cfg.setEntityNotFoundDelegate( jpaEntityNotFoundDelegate );
if ( namingStrategy != null ) {
cfg.setNamingStrategy( namingStrategy );
}
if ( sessionFactoryInterceptor != null ) {
cfg.setInterceptor( sessionFactoryInterceptor );
}
final Object strategyProviderValue = props.get( AvailableSettings.IDENTIFIER_GENERATOR_STRATEGY_PROVIDER );
final IdentifierGeneratorStrategyProvider strategyProvider = strategyProviderValue == null
? null
: serviceRegistry.getService( StrategySelector.class )
.resolveStrategy( IdentifierGeneratorStrategyProvider.class, strategyProviderValue );
if ( strategyProvider != null ) {
final MutableIdentifierGeneratorFactory identifierGeneratorFactory = cfg.getIdentifierGeneratorFactory();
for ( Map.Entry<String,Class<?>> entry : strategyProvider.getStrategies().entrySet() ) {
identifierGeneratorFactory.register( entry.getKey(), entry.getValue() );
}
}
<<<<<<< HEAD
if ( grantedJaccPermissions != null ) {
final JaccService jaccService = serviceRegistry.getService( JaccService.class );
for ( GrantedPermission grantedPermission : grantedJaccPermissions ) {
jaccService.addPermission( grantedPermission );
=======
if ( jaccDefinitions != null ) {
for ( JaccDefinition jaccDefinition : jaccDefinitions ) {
JACCConfiguration jaccCfg = new JACCConfiguration( jaccDefinition.getContextId() );
jaccCfg.addPermission(
jaccDefinition.getRole(),
jaccDefinition.getClazz(),
jaccDefinition.getActions()
);
>>>>>>> HHH-6159 - Create EntityManagerFactoryBuilder : integrate EntityManagerFactoryBuilder with metamodel codebase
}
}
if ( cacheRegionDefinitions != null ) {
for ( CacheRegionDefinition cacheRegionDefinition : cacheRegionDefinitions ) {
if ( cacheRegionDefinition.getRegionType() == CacheRegionDefinition.CacheRegionType.ENTITY ) {
cfg.setCacheConcurrencyStrategy(
cacheRegionDefinition.getRole(),
cacheRegionDefinition.getUsage(),
cacheRegionDefinition.getRegion(),
cacheRegionDefinition.isCacheLazy()
);
}
else {
cfg.setCollectionCacheConcurrencyStrategy(
cacheRegionDefinition.getRole(),
cacheRegionDefinition.getUsage(),
cacheRegionDefinition.getRegion()
);
}
}
}
// todo : need to have this use the metamodel codebase eventually...
for ( JaxbMapping jaxbMapping : cfgXmlNamedMappings ) {
if ( jaxbMapping.getClazz() != null ) {
cfg.addAnnotatedClass(
serviceRegistry.getService( ClassLoaderService.class ).classForName( jaxbMapping.getClazz() )
);
}
else if ( jaxbMapping.getResource() != null ) {
cfg.addResource( jaxbMapping.getResource() );
}
else if ( jaxbMapping.getJar() != null ) {
cfg.addJar( new File( jaxbMapping.getJar() ) );
}
else if ( jaxbMapping.getPackage() != null ) {
cfg.addPackage( jaxbMapping.getPackage() );
}
}
List<Class> loadedAnnotatedClasses = (List<Class>) configurationValues.remove( AvailableSettings.LOADED_CLASSES );
if ( loadedAnnotatedClasses != null ) {
for ( Class cls : loadedAnnotatedClasses ) {
if ( AttributeConverter.class.isAssignableFrom( cls ) ) {
cfg.addAttributeConverter( (Class<? extends AttributeConverter>) cls );
}
else {
cfg.addAnnotatedClass( cls );
}
}
}
for ( String className : metadataSources.getAnnotatedMappingClassNames() ) {
cfg.addAnnotatedClass( serviceRegistry.getService( ClassLoaderService.class ).classForName( className ) );
}
for ( MetadataSources.ConverterDescriptor converterDescriptor : metadataSources.getConverterDescriptors() ) {
final Class<? extends AttributeConverter> converterClass;
try {
Class theClass = serviceRegistry.getService( ClassLoaderService.class ).classForName( converterDescriptor.converterClassName );
converterClass = (Class<? extends AttributeConverter>) theClass;
}
catch (ClassCastException e) {
throw persistenceException(
String.format(
"AttributeConverter implementation [%s] does not implement AttributeConverter interface",
converterDescriptor.converterClassName
)
);
}
cfg.addAttributeConverter( converterClass, converterDescriptor.autoApply );
}
for ( String resourceName : metadataSources.mappingFileResources ) {
Boolean useMetaInf = null;
try {
if ( resourceName.endsWith( META_INF_ORM_XML ) ) {
useMetaInf = true;
}
cfg.addResource( resourceName );
}
catch( MappingNotFoundException e ) {
if ( ! resourceName.endsWith( META_INF_ORM_XML ) ) {
throw persistenceException( "Unable to find XML mapping file in classpath: " + resourceName );
}
else {
useMetaInf = false;
//swallow it, the META-INF/orm.xml is optional
}
}
catch( MappingException me ) {
throw persistenceException( "Error while reading JPA XML file: " + resourceName, me );
}
if ( Boolean.TRUE.equals( useMetaInf ) ) {
LOG.exceptionHeaderFound( getExceptionHeader(), META_INF_ORM_XML );
}
else if (Boolean.FALSE.equals(useMetaInf)) {
LOG.exceptionHeaderNotFound( getExceptionHeader(), META_INF_ORM_XML );
}
}
for ( NamedInputStream namedInputStream : metadataSources.namedMappingFileInputStreams ) {
try {
//addInputStream has the responsibility to close the stream
cfg.addInputStream( new BufferedInputStream( namedInputStream.getStream() ) );
}
catch ( InvalidMappingException e ) {
// try our best to give the file name
if ( StringHelper.isNotEmpty( namedInputStream.getName() ) ) {
throw new InvalidMappingException(
"Error while parsing file: " + namedInputStream.getName(),
e.getType(),
e.getPath(),
e
);
}
else {
throw e;
}
}
catch (MappingException me) {
// try our best to give the file name
if ( StringHelper.isNotEmpty( namedInputStream.getName() ) ) {
throw new MappingException("Error while parsing file: " + namedInputStream.getName(), me );
}
else {
throw me;
}
}
}
for ( String packageName : metadataSources.packageNames ) {
cfg.addPackage( packageName );
}
final TypeContributorList typeContributorList
= (TypeContributorList) configurationValues.get( TYPE_CONTRIBUTORS );
if ( typeContributorList != null ) {
configurationValues.remove( TYPE_CONTRIBUTORS );
for ( TypeContributor typeContributor : typeContributorList.getTypeContributors() ) {
cfg.registerTypeContributor( typeContributor );
}
}
return cfg;
}
public static class ServiceRegistryCloser implements SessionFactoryObserver {
@Override
public void sessionFactoryCreated(SessionFactory sessionFactory) {
// nothing to do
}
@Override
public void sessionFactoryClosed(SessionFactory sessionFactory) {
SessionFactoryImplementor sfi = ( (SessionFactoryImplementor) sessionFactory );
sfi.getServiceRegistry().destroy();
ServiceRegistry basicRegistry = sfi.getServiceRegistry().getParentServiceRegistry();
( (ServiceRegistryImplementor) basicRegistry ).destroy();
}
}
private PersistenceException persistenceException(String message) {
return persistenceException( message, null );
}
private PersistenceException persistenceException(String message, Exception cause) {
return new PersistenceException(
getExceptionHeader() + message,
cause
);
}
private String getExceptionHeader() {
return "[PersistenceUnit: " + persistenceUnit.getName() + "] ";
}
<<<<<<< HEAD
public static class CacheRegionDefinition {
public static enum CacheType { ENTITY, COLLECTION }
public final CacheType cacheType;
public final String role;
public final String usage;
public final String region;
public final boolean cacheLazy;
public CacheRegionDefinition(
CacheType cacheType,
String role,
String usage,
String region, boolean cacheLazy) {
this.cacheType = cacheType;
this.role = role;
this.usage = usage;
this.region = region;
this.cacheLazy = cacheLazy;
}
}
public static class JaccDefinition {
public final String contextId;
public final String role;
public final String clazz;
public final String actions;
public JaccDefinition(String contextId, String role, String clazz, String actions) {
this.contextId = contextId;
this.role = role;
this.clazz = clazz;
this.actions = actions;
=======
public static class ScanningContext {
private URL url;
private boolean detectClasses;
private boolean detectHbmFiles;
private boolean searchOrm;
public URL getUrl() {
return url;
}
public void setUrl(URL url) {
this.url = url;
}
public boolean isDetectClasses() {
return detectClasses;
}
public void setDetectClasses(boolean detectClasses) {
this.detectClasses = detectClasses;
}
public boolean isDetectHbmFiles() {
return detectHbmFiles;
}
public void setDetectHbmFiles(boolean detectHbmFiles) {
this.detectHbmFiles = detectHbmFiles;
}
public boolean isSearchOrm() {
return searchOrm;
}
public void setSearchOrm(boolean searchOrm) {
this.searchOrm = searchOrm;
}
}
private static class ScanResult {
private final List<String> managedClassNames = new ArrayList<String>();
private final List<String> packageNames = new ArrayList<String>();
private final List<NamedInputStream> hbmFiles = new ArrayList<NamedInputStream>();
private final List<String> mappingFiles = new ArrayList<String>();
public List<String> getManagedClassNames() {
return managedClassNames;
}
public List<String> getPackageNames() {
return packageNames;
}
public List<NamedInputStream> getHbmFiles() {
return hbmFiles;
}
public List<String> getMappingFiles() {
return mappingFiles;
>>>>>>> HHH-6159 - Create EntityManagerFactoryBuilder : integrate EntityManagerFactoryBuilder with metamodel codebase
}
}
public static class MetadataSources {
private final List<String> annotatedMappingClassNames = new ArrayList<String>();
private final List<ConverterDescriptor> converterDescriptors = new ArrayList<ConverterDescriptor>();
private final List<NamedInputStream> namedMappingFileInputStreams = new ArrayList<NamedInputStream>();
private final List<String> mappingFileResources = new ArrayList<String>();
private final List<String> packageNames = new ArrayList<String>();
public List<String> getAnnotatedMappingClassNames() {
return annotatedMappingClassNames;
}
public List<ConverterDescriptor> getConverterDescriptors() {
return converterDescriptors;
}
public List<NamedInputStream> getNamedMappingFileInputStreams() {
return namedMappingFileInputStreams;
}
public List<String> getPackageNames() {
return packageNames;
}
public List<String> collectMappingClassNames() {
// todo : the complete answer to this involves looking through the mapping files as well.
// Really need the metamodel branch code to do that properly
return annotatedMappingClassNames;
}
public static class ConverterDescriptor {
private final String converterClassName;
private final boolean autoApply;
public ConverterDescriptor(String converterClassName, boolean autoApply) {
this.converterClassName = converterClassName;
this.autoApply = autoApply;
}
}
}
}
public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
private static final long serialVersionUID = 5423543L;
private static final IdentifierGenerator UUID_GENERATOR = UUIDGenerator.buildSessionFactoryUniqueIdentifierGenerator();
private static final Logger log = Logger.getLogger( EntityManagerFactoryImpl.class );
private final transient SessionFactoryImpl sessionFactory;
private final transient PersistenceUnitTransactionType transactionType;
private final transient boolean discardOnClose;
private final transient Class sessionInterceptorClass;
private final transient CriteriaBuilderImpl criteriaBuilder;
private final transient MetamodelImpl metamodel;
private final transient HibernatePersistenceUnitUtil util;
private final transient Map<String,Object> properties;
private final String entityManagerFactoryName;
private final transient PersistenceUtilHelper.MetadataCache cache = new PersistenceUtilHelper.MetadataCache();
private final transient Map<String,EntityGraphImpl> entityGraphs = new ConcurrentHashMap<String, EntityGraphImpl>();
@SuppressWarnings( "unchecked" )
public EntityManagerFactoryImpl(
PersistenceUnitTransactionType transactionType,
boolean discardOnClose,
Class sessionInterceptorClass,
Configuration cfg,
ServiceRegistry serviceRegistry,
String persistenceUnitName) {
this(
persistenceUnitName,
(SessionFactoryImplementor) cfg.buildSessionFactory( serviceRegistry ),
new SettingsImpl().setReleaseResourcesOnCloseEnabled( discardOnClose ).setSessionInterceptorClass( sessionInterceptorClass ).setTransactionType( transactionType ),
cfg.getProperties(),
cfg
);
}
public EntityManagerFactoryImpl(
String persistenceUnitName,
SessionFactoryImplementor sessionFactory,
SettingsImpl settings,
Map<?, ?> configurationValues,
Configuration cfg) {
this.sessionFactory = (SessionFactoryImpl) sessionFactory;
this.transactionType = settings.getTransactionType();
this.discardOnClose = settings.isReleaseResourcesOnCloseEnabled();
this.sessionInterceptorClass = settings.getSessionInterceptorClass();
<<<<<<< HEAD
final JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting = determineJpaMetaModelPopulationSetting( cfg );
if ( JpaMetaModelPopulationSetting.DISABLED == jpaMetaModelPopulationSetting ) {
this.metamodel = null;
}
else {
this.metamodel = MetamodelImpl.buildMetamodel(
cfg.getClassMappings(),
cfg.getMappedSuperclassMappingsCopy(),
sessionFactory,
JpaMetaModelPopulationSetting.IGNORE_UNSUPPORTED == jpaMetaModelPopulationSetting
);
}
=======
this.metamodel = sessionFactory.getJpaMetamodel();
>>>>>>> HHH-6159 - Create EntityManagerFactoryBuilder : integrate EntityManagerFactoryBuilder with metamodel codebase
this.criteriaBuilder = new CriteriaBuilderImpl( this );
this.util = new HibernatePersistenceUnitUtil( this );
HashMap<String,Object> props = new HashMap<String, Object>();
addAll( props, sessionFactory.getProperties() );
addAll( props, cfg.getProperties() );
addAll( props, configurationValues );
maskOutSensitiveInformation( props );
this.properties = Collections.unmodifiableMap( props );
String entityManagerFactoryName = (String)this.properties.get( AvailableSettings.ENTITY_MANAGER_FACTORY_NAME);
if (entityManagerFactoryName == null) {
entityManagerFactoryName = persistenceUnitName;
}
if (entityManagerFactoryName == null) {
entityManagerFactoryName = (String) UUID_GENERATOR.generate(null, null);
}
this.entityManagerFactoryName = entityManagerFactoryName;
applyNamedEntityGraphs( cfg.getNamedEntityGraphs() );
EntityManagerFactoryRegistry.INSTANCE.addEntityManagerFactory( entityManagerFactoryName, this );
}
private static void addAll(HashMap<String, Object> destination, Map<?,?> source) {
for ( Map.Entry entry : source.entrySet() ) {
if ( String.class.isInstance( entry.getKey() ) ) {
destination.put( (String) entry.getKey(), entry.getValue() );
}
}
}
private void maskOutSensitiveInformation(HashMap<String, Object> props) {
maskOutIfSet( props, AvailableSettings.JDBC_PASSWORD );
maskOutIfSet( props, org.hibernate.cfg.AvailableSettings.PASS );
}
private void maskOutIfSet(HashMap<String, Object> props, String setting) {
if ( props.containsKey( setting ) ) {
props.put( setting, "****" );
}
}
@SuppressWarnings("unchecked")
private void applyNamedEntityGraphs(Collection<NamedEntityGraphDefinition> namedEntityGraphs) {
for ( NamedEntityGraphDefinition definition : namedEntityGraphs ) {
log.debugf(
"Applying named entity graph [name=%s, entity-name=%s, jpa-entity-name=%s",
definition.getRegisteredName(),
definition.getEntityName(),
definition.getJpaEntityName()
);
final EntityType entityType = metamodel.getEntityTypeByName( definition.getEntityName() );
if ( entityType == null ) {
throw new IllegalArgumentException(
"Attempted to register named entity graph [" + definition.getRegisteredName()
+ "] for unknown entity ["+ definition.getEntityName() + "]"
);
}
final EntityGraphImpl entityGraph = new EntityGraphImpl(
definition.getRegisteredName(),
entityType,
this
);
final NamedEntityGraph namedEntityGraph = definition.getAnnotation();
if ( namedEntityGraph.includeAllAttributes() ) {
for ( Object attributeObject : entityType.getAttributes() ) {
entityGraph.addAttributeNodes( (Attribute) attributeObject );
}
}
if ( namedEntityGraph.attributeNodes() != null ) {
applyNamedAttributeNodes( namedEntityGraph.attributeNodes(), namedEntityGraph, entityGraph );
}
entityGraphs.put( definition.getRegisteredName(), entityGraph );
}
}
private void applyNamedAttributeNodes(
NamedAttributeNode[] namedAttributeNodes,
NamedEntityGraph namedEntityGraph,
AbstractGraphNode graphNode) {
for ( NamedAttributeNode namedAttributeNode : namedAttributeNodes ) {
final String value = namedAttributeNode.value();
AttributeNodeImpl attributeNode = graphNode.addAttribute( value );
if ( StringHelper.isNotEmpty( namedAttributeNode.subgraph() ) ) {
final SubgraphImpl subgraph = attributeNode.makeSubgraph();
applyNamedSubgraphs(
namedEntityGraph,
namedAttributeNode.subgraph(),
subgraph
);
}
if ( StringHelper.isNotEmpty( namedAttributeNode.keySubgraph() ) ) {
final SubgraphImpl subgraph = attributeNode.makeKeySubgraph();
applyNamedSubgraphs(
namedEntityGraph,
namedAttributeNode.keySubgraph(),
subgraph
);
}
}
}
private void applyNamedSubgraphs(NamedEntityGraph namedEntityGraph, String subgraphName, SubgraphImpl subgraph) {
for ( NamedSubgraph namedSubgraph : namedEntityGraph.subgraphs() ) {
if ( subgraphName.equals( namedSubgraph.name() ) ) {
applyNamedAttributeNodes(
namedSubgraph.attributeNodes(),
namedEntityGraph,
subgraph
);
}
}
}
public EntityManager createEntityManager() {
return internalCreateEntityManager( SynchronizationType.SYNCHRONIZED, Collections.EMPTY_MAP );
}
@Override
public EntityManager createEntityManager(SynchronizationType synchronizationType) {
errorIfResourceLocalDueToExplicitSynchronizationType();
return internalCreateEntityManager( synchronizationType, Collections.EMPTY_MAP );
}
private void errorIfResourceLocalDueToExplicitSynchronizationType() {
if ( transactionType == PersistenceUnitTransactionType.RESOURCE_LOCAL ) {
throw new IllegalStateException(
"Illegal attempt to specify a SynchronizationType when building an EntityManager from a " +
"EntityManagerFactory defined as RESOURCE_LOCAL "
);
}
}
public EntityManager createEntityManager(Map map) {
return internalCreateEntityManager( SynchronizationType.SYNCHRONIZED, map );
}
@Override
public EntityManager createEntityManager(SynchronizationType synchronizationType, Map map) {
errorIfResourceLocalDueToExplicitSynchronizationType();
return internalCreateEntityManager( synchronizationType, map );
}
private EntityManager internalCreateEntityManager(SynchronizationType synchronizationType, Map map) {
validateNotClosed();
//TODO support discardOnClose, persistencecontexttype?, interceptor,
return new EntityManagerImpl(
this,
PersistenceContextType.EXTENDED,
synchronizationType,
transactionType,
discardOnClose,
sessionInterceptorClass,
map
);
}
public CriteriaBuilder getCriteriaBuilder() {
validateNotClosed();
return criteriaBuilder;
}
public Metamodel getMetamodel() {
validateNotClosed();
return metamodel;
}
public void close() {
// The spec says so, that's why :(
validateNotClosed();
sessionFactory.close();
EntityManagerFactoryRegistry.INSTANCE.removeEntityManagerFactory(entityManagerFactoryName, this);
}
public Map<String, Object> getProperties() {
validateNotClosed();
return properties;
}
public Cache getCache() {
validateNotClosed();
// TODO : cache the cache reference?
return new JPACache( sessionFactory );
}
protected void validateNotClosed() {
if ( ! isOpen() ) {
throw new IllegalStateException( "EntityManagerFactory is closed" );
}
}
public PersistenceUnitUtil getPersistenceUnitUtil() {
validateNotClosed();
return util;
}
@Override
public void addNamedQuery(String name, Query query) {
validateNotClosed();
// NOTE : we use Query#unwrap here (rather than direct type checking) to account for possibly wrapped
// query implementations
// first, handle StoredProcedureQuery
try {
final StoredProcedureQueryImpl unwrapped = query.unwrap( StoredProcedureQueryImpl.class );
if ( unwrapped != null ) {
addNamedStoredProcedureQuery( name, unwrapped );
return;
}
}
catch ( PersistenceException ignore ) {
// this means 'query' is not a StoredProcedureQueryImpl
}
// then try as a native-SQL or JPQL query
try {
final HibernateQuery unwrapped = query.unwrap( HibernateQuery.class );
if ( unwrapped != null ) {
// create and register the proper NamedQueryDefinition...
final org.hibernate.Query hibernateQuery = unwrapped.getHibernateQuery();
if ( org.hibernate.SQLQuery.class.isInstance( hibernateQuery ) ) {
sessionFactory.registerNamedSQLQueryDefinition(
name,
extractSqlQueryDefinition( (org.hibernate.SQLQuery) hibernateQuery, name )
);
}
else {
sessionFactory.registerNamedQueryDefinition( name, extractHqlQueryDefinition( hibernateQuery, name ) );
}
return;
}
}
catch ( PersistenceException ignore ) {
// this means 'query' is not a native-SQL or JPQL query
}
// if we get here, we are unsure how to properly unwrap the incoming query to extract the needed information
throw new PersistenceException(
String.format(
"Unsure how to how to properly unwrap given Query [%s] as basis for named query",
query
)
);
}
private void addNamedStoredProcedureQuery(String name, StoredProcedureQueryImpl query) {
final ProcedureCall procedureCall = query.getHibernateProcedureCall();
sessionFactory.getNamedQueryRepository().registerNamedProcedureCallMemento(
name,
procedureCall.extractMemento( query.getHints() )
);
}
private NamedSQLQueryDefinition extractSqlQueryDefinition(org.hibernate.SQLQuery nativeSqlQuery, String name) {
final NamedSQLQueryDefinitionBuilder builder = new NamedSQLQueryDefinitionBuilder( name );
fillInNamedQueryBuilder( builder, nativeSqlQuery );
builder.setCallable( nativeSqlQuery.isCallable() )
.setQuerySpaces( nativeSqlQuery.getSynchronizedQuerySpaces() )
.setQueryReturns( nativeSqlQuery.getQueryReturns() );
return builder.createNamedQueryDefinition();
}
private NamedQueryDefinition extractHqlQueryDefinition(org.hibernate.Query hqlQuery, String name) {
final NamedQueryDefinitionBuilder builder = new NamedQueryDefinitionBuilder( name );
fillInNamedQueryBuilder( builder, hqlQuery );
// LockOptions only valid for HQL/JPQL queries...
builder.setLockOptions( hqlQuery.getLockOptions().makeCopy() );
return builder.createNamedQueryDefinition();
}
private void fillInNamedQueryBuilder(NamedQueryDefinitionBuilder builder, org.hibernate.Query query) {
builder.setQuery( query.getQueryString() )
.setComment( query.getComment() )
.setCacheable( query.isCacheable() )
.setCacheRegion( query.getCacheRegion() )
.setCacheMode( query.getCacheMode() )
.setTimeout( query.getTimeout() )
.setFetchSize( query.getFetchSize() )
.setFirstResult( query.getFirstResult() )
.setMaxResults( query.getMaxResults() )
.setReadOnly( query.isReadOnly() )
.setFlushMode( query.getFlushMode() );
}
@Override
@SuppressWarnings("unchecked")
public <T> T unwrap(Class<T> cls) {
if ( SessionFactory.class.isAssignableFrom( cls ) ) {
return ( T ) sessionFactory;
}
if ( SessionFactoryImplementor.class.isAssignableFrom( cls ) ) {
return ( T ) sessionFactory;
}
if ( EntityManager.class.isAssignableFrom( cls ) ) {
return ( T ) this;
}
throw new PersistenceException( "Hibernate cannot unwrap EntityManagerFactory as " + cls.getName() );
}
@Override
public <T> void addNamedEntityGraph(String graphName, EntityGraph<T> entityGraph) {
if ( ! EntityGraphImpl.class.isInstance( entityGraph ) ) {
throw new IllegalArgumentException(
"Unknown type of EntityGraph for making named : " + entityGraph.getClass().getName()
);
}
final EntityGraphImpl<T> copy = ( (EntityGraphImpl<T>) entityGraph ).makeImmutableCopy( graphName );
final EntityGraphImpl old = entityGraphs.put( graphName, copy );
if ( old != null ) {
log.debugf( "EntityGraph being replaced on EntityManagerFactory for name %s", graphName );
}
}
public EntityGraphImpl findEntityGraphByName(String name) {
return entityGraphs.get( name );
}
@SuppressWarnings("unchecked")
public <T> List<EntityGraph<? super T>> findEntityGraphsByType(Class<T> entityClass) {
final EntityType<T> entityType = getMetamodel().entity( entityClass );
if ( entityType == null ) {
throw new IllegalArgumentException( "Given class is not an entity : " + entityClass.getName() );
}
final List<EntityGraph<? super T>> results = new ArrayList<EntityGraph<? super T>>();
for ( EntityGraphImpl entityGraph : this.entityGraphs.values() ) {
if ( entityGraph.appliesTo( entityType ) ) {
results.add( entityGraph );
}
}
return results;
}
public boolean isOpen() {
return ! sessionFactory.isClosed();
}
public SessionFactoryImpl getSessionFactory() {
return sessionFactory;
}
@Override
public EntityTypeImpl getEntityTypeByName(String entityName) {
final EntityTypeImpl entityType = metamodel.getEntityTypeByName( entityName );
if ( entityType == null ) {
throw new IllegalArgumentException( "[" + entityName + "] did not refer to EntityType" );
}
return entityType;
}
public String getEntityManagerFactoryName() {
return entityManagerFactoryName;
}
private static class JPACache implements Cache {
private SessionFactoryImplementor sessionFactory;
private JPACache(SessionFactoryImplementor sessionFactory) {
this.sessionFactory = sessionFactory;
}
public boolean contains(Class entityClass, Object identifier) {
return sessionFactory.getCache().containsEntity( entityClass, ( Serializable ) identifier );
}
public void evict(Class entityClass, Object identifier) {
sessionFactory.getCache().evictEntity( entityClass, ( Serializable ) identifier );
}
public void evict(Class entityClass) {
sessionFactory.getCache().evictEntityRegion( entityClass );
}
public void evictAll() {
// Evict only the "JPA cache", which is purely defined as the entity regions.
sessionFactory.getCache().evictEntityRegions();
// TODO : if we want to allow an optional clearing of all cache data, the additional calls would be:
// sessionFactory.getCache().evictCollectionRegions();
// sessionFactory.getCache().evictQueryRegions();
}
@Override
@SuppressWarnings("unchecked")
public <T> T unwrap(Class<T> cls) {
if ( RegionFactory.class.isAssignableFrom( cls ) ) {
return (T) sessionFactory.getSettings().getRegionFactory();
}
if ( org.hibernate.Cache.class.isAssignableFrom( cls ) ) {
return (T) sessionFactory.getCache();
}
throw new PersistenceException( "Hibernate cannot unwrap Cache as " + cls.getName() );
}
}
private static EntityManagerFactory getNamedEntityManagerFactory(String entityManagerFactoryName) throws InvalidObjectException {
Object result = EntityManagerFactoryRegistry.INSTANCE.getNamedEntityManagerFactory(entityManagerFactoryName);
if ( result == null ) {
throw new InvalidObjectException( "could not resolve entity manager factory during entity manager deserialization [name=" + entityManagerFactoryName + "]" );
}
return (EntityManagerFactory)result;
}
private void writeObject(ObjectOutputStream oos) throws IOException {
if (entityManagerFactoryName == null) {
throw new InvalidObjectException( "could not serialize entity manager factory with null entityManagerFactoryName" );
}
oos.defaultWriteObject();
}
/**
* After deserialization of an EntityManagerFactory, this is invoked to return the EntityManagerFactory instance
* that is already in use rather than a cloned copy of the object.
*
* @return
* @throws InvalidObjectException
*/
private Object readResolve() throws InvalidObjectException {
return getNamedEntityManagerFactory(entityManagerFactoryName);
}
private static class HibernatePersistenceUnitUtil implements PersistenceUnitUtil, Serializable {
private final HibernateEntityManagerFactory emf;
private transient PersistenceUtilHelper.MetadataCache cache;
private HibernatePersistenceUnitUtil(EntityManagerFactoryImpl emf) {
this.emf = emf;
this.cache = emf.cache;
}
public boolean isLoaded(Object entity, String attributeName) {
// added log message to help with HHH-7454, if state == LoadState,NOT_LOADED, returning true or false is not accurate.
log.debug("PersistenceUnitUtil#isLoaded is not always accurate; consider using EntityManager#contains instead");
LoadState state = PersistenceUtilHelper.isLoadedWithoutReference( entity, attributeName, cache );
if (state == LoadState.LOADED) {
return true;
}
else if (state == LoadState.NOT_LOADED ) {
return false;
}
else {
return PersistenceUtilHelper.isLoadedWithReference( entity, attributeName, cache ) != LoadState.NOT_LOADED;
}
}
public boolean isLoaded(Object entity) {
// added log message to help with HHH-7454, if state == LoadState,NOT_LOADED, returning true or false is not accurate.
log.debug("PersistenceUnitUtil#isLoaded is not always accurate; consider using EntityManager#contains instead");
return PersistenceUtilHelper.isLoaded( entity ) != LoadState.NOT_LOADED;
}
public Object getIdentifier(Object entity) {
final Class entityClass = Hibernate.getClass( entity );
final ClassMetadata classMetadata = emf.getSessionFactory().getClassMetadata( entityClass );
if (classMetadata == null) {
throw new IllegalArgumentException( entityClass + " is not an entity" );
}
//TODO does that work for @IdClass?
return classMetadata.getIdentifier( entity );
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment