Skip to content

Commit 8b5bc44

Browse files
quaffbeikov
authored andcommitted
HHH-15422 Pick up ConnectionProvider from BeanContainer if not explicit set
1 parent 657e7a2 commit 8b5bc44

File tree

2 files changed

+179
-13
lines changed

2 files changed

+179
-13
lines changed

hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/ConnectionProviderInitiator.java

Lines changed: 75 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55
package org.hibernate.engine.jdbc.connections.internal;
66

7+
import java.lang.reflect.InvocationTargetException;
78
import java.sql.Connection;
89
import java.util.Collection;
910
import java.util.HashSet;
@@ -19,6 +20,11 @@
1920
import org.hibernate.internal.CoreLogging;
2021
import org.hibernate.internal.CoreMessageLogger;
2122
import org.hibernate.internal.util.StringHelper;
23+
import org.hibernate.resource.beans.container.spi.BeanContainer;
24+
import org.hibernate.resource.beans.internal.FallbackBeanInstanceProducer;
25+
import org.hibernate.resource.beans.internal.Helper;
26+
import org.hibernate.resource.beans.spi.BeanInstanceProducer;
27+
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
2228
import org.hibernate.service.spi.ServiceRegistryImplementor;
2329

2430
import static java.sql.Connection.TRANSACTION_NONE;
@@ -102,6 +108,7 @@ public ConnectionProvider initiateService(
102108
return null;
103109
}
104110

111+
final BeanContainer beanContainer = Helper.allowExtensionsInCdi( registry ) ? registry.requireService( ManagedBeanRegistry.class ).getBeanContainer() : null;
105112
final StrategySelector strategySelector = registry.requireService( StrategySelector.class );
106113
final Object explicitSetting = configurationValues.get( CONNECTION_PROVIDER );
107114
if ( explicitSetting != null ) {
@@ -111,25 +118,25 @@ public ConnectionProvider initiateService(
111118
}
112119
else if ( explicitSetting instanceof Class<?> providerClass ) {
113120
LOG.instantiatingExplicitConnectionProvider( providerClass.getName() );
114-
return instantiateExplicitConnectionProvider( providerClass );
121+
return instantiateExplicitConnectionProvider( providerClass, beanContainer );
115122
}
116123
else {
117124
final String providerName = nullIfEmpty( explicitSetting.toString() );
118125
if ( providerName != null ) {
119-
return instantiateNamedConnectionProvider(providerName, strategySelector);
126+
return instantiateNamedConnectionProvider(providerName, strategySelector, beanContainer);
120127
}
121128
}
122129
}
123130

124-
return instantiateConnectionProvider( configurationValues, strategySelector );
131+
return instantiateConnectionProvider( configurationValues, strategySelector, beanContainer );
125132
}
126133

127-
private ConnectionProvider instantiateNamedConnectionProvider(String providerName, StrategySelector strategySelector) {
134+
private ConnectionProvider instantiateNamedConnectionProvider(String providerName, StrategySelector strategySelector, BeanContainer beanContainer) {
128135
LOG.instantiatingExplicitConnectionProvider( providerName );
129136
final Class<?> providerClass =
130137
strategySelector.selectStrategyImplementor( ConnectionProvider.class, providerName );
131138
try {
132-
return instantiateExplicitConnectionProvider( providerClass );
139+
return instantiateExplicitConnectionProvider( providerClass, beanContainer );
133140
}
134141
catch (Exception e) {
135142
throw new HibernateException(
@@ -140,7 +147,7 @@ private ConnectionProvider instantiateNamedConnectionProvider(String providerNam
140147
}
141148

142149
private ConnectionProvider instantiateConnectionProvider(
143-
Map<String, Object> configurationValues, StrategySelector strategySelector) {
150+
Map<String, Object> configurationValues, StrategySelector strategySelector, BeanContainer beanContainer) {
144151
if ( configurationValues.containsKey( DATASOURCE ) ) {
145152
return new DatasourceConnectionProviderImpl();
146153
}
@@ -149,9 +156,9 @@ private ConnectionProvider instantiateConnectionProvider(
149156
getSingleRegisteredProvider( strategySelector );
150157
if ( singleRegisteredProvider != null ) {
151158
try {
152-
return singleRegisteredProvider.newInstance();
159+
return singleRegisteredProvider.getConstructor().newInstance();
153160
}
154-
catch (IllegalAccessException | InstantiationException e) {
161+
catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException | InstantiationException e) {
155162
throw new HibernateException( "Could not instantiate singular-registered ConnectionProvider", e );
156163
}
157164
}
@@ -177,11 +184,47 @@ else if ( configurationValues.containsKey( URL ) ) {
177184
return new DriverManagerConnectionProviderImpl();
178185
}
179186
else {
180-
LOG.noAppropriateConnectionProvider();
181-
return new UserSuppliedConnectionProviderImpl();
187+
if (beanContainer != null) {
188+
return beanContainer.getBean(
189+
ConnectionProvider.class,
190+
new BeanContainer.LifecycleOptions() {
191+
@Override
192+
public boolean canUseCachedReferences() {
193+
return true;
194+
}
195+
196+
@Override
197+
public boolean useJpaCompliantCreation() {
198+
return true;
199+
}
200+
},
201+
new BeanInstanceProducer() {
202+
203+
@Override
204+
public <B> B produceBeanInstance(Class<B> beanType) {
205+
return (B) noAppropriateConnectionProvider();
206+
}
207+
208+
@Override
209+
public <B> B produceBeanInstance(String name, Class<B> beanType) {
210+
return (B) noAppropriateConnectionProvider();
211+
}
212+
213+
}
214+
).getBeanInstance();
215+
}
216+
else {
217+
return noAppropriateConnectionProvider();
218+
}
219+
182220
}
183221
}
184222

223+
private ConnectionProvider noAppropriateConnectionProvider() {
224+
LOG.noAppropriateConnectionProvider();
225+
return new UserSuppliedConnectionProviderImpl();
226+
}
227+
185228
private Class<? extends ConnectionProvider> getSingleRegisteredProvider(StrategySelector strategySelector) {
186229
final Collection<Class<? extends ConnectionProvider>> implementors =
187230
strategySelector.getRegisteredStrategyImplementors( ConnectionProvider.class );
@@ -190,9 +233,28 @@ private Class<? extends ConnectionProvider> getSingleRegisteredProvider(Strategy
190233
: null;
191234
}
192235

193-
private ConnectionProvider instantiateExplicitConnectionProvider(Class<?> providerClass) {
236+
private ConnectionProvider instantiateExplicitConnectionProvider(Class<?> providerClass, BeanContainer beanContainer) {
194237
try {
195-
return (ConnectionProvider) providerClass.newInstance();
238+
if ( beanContainer != null ) {
239+
return (ConnectionProvider) beanContainer.getBean(
240+
providerClass,
241+
new BeanContainer.LifecycleOptions() {
242+
@Override
243+
public boolean canUseCachedReferences() {
244+
return true;
245+
}
246+
247+
@Override
248+
public boolean useJpaCompliantCreation() {
249+
return true;
250+
}
251+
},
252+
FallbackBeanInstanceProducer.INSTANCE
253+
).getBeanInstance();
254+
}
255+
else {
256+
return (ConnectionProvider) providerClass.getConstructor().newInstance();
257+
}
196258
}
197259
catch (Exception e) {
198260
throw new HibernateException( "Could not instantiate connection provider [" + providerClass.getName() + "]", e );
@@ -201,7 +263,7 @@ private ConnectionProvider instantiateExplicitConnectionProvider(Class<?> provid
201263

202264
private static ConnectionProvider instantiateProvider(StrategySelector selector, String strategy) {
203265
try {
204-
return selector.selectStrategyImplementor( ConnectionProvider.class, strategy ).newInstance();
266+
return selector.selectStrategyImplementor( ConnectionProvider.class, strategy ).getConstructor().newInstance();
205267
}
206268
catch ( Exception e ) {
207269
LOG.providerClassNotFound(strategy);
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* SPDX-License-Identifier: LGPL-2.1-or-later
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.connections;
6+
7+
import org.hibernate.cfg.AvailableSettings;
8+
import org.hibernate.dialect.H2Dialect;
9+
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
10+
import org.hibernate.resource.beans.container.spi.BeanContainer;
11+
import org.hibernate.resource.beans.container.spi.ContainedBean;
12+
import org.hibernate.resource.beans.spi.BeanInstanceProducer;
13+
import org.hibernate.service.ServiceRegistry;
14+
import org.hibernate.testing.junit4.BaseUnitTestCase;
15+
import org.hibernate.testing.orm.junit.RequiresDialect;
16+
import org.hibernate.testing.util.ServiceRegistryUtil;
17+
import org.junit.Test;
18+
19+
import java.sql.Connection;
20+
import java.sql.SQLException;
21+
import java.util.HashMap;
22+
import java.util.Map;
23+
24+
import static org.hibernate.cfg.JdbcSettings.CONNECTION_PROVIDER;
25+
import static org.junit.Assert.assertSame;
26+
27+
/**
28+
* @author Yanming Zhou
29+
*/
30+
@RequiresDialect(H2Dialect.class)
31+
public class ConnectionProviderFromBeanContainerTest extends BaseUnitTestCase {
32+
33+
private final ConnectionProvider dummyConnectionProvider = new DummyConnectionProvider();
34+
35+
private Map<String, Object> createSettings() {
36+
Map<String, Object> settings = new HashMap<>();
37+
settings.put( AvailableSettings.ALLOW_EXTENSIONS_IN_CDI, "true" );
38+
settings.put( AvailableSettings.BEAN_CONTAINER, new BeanContainer() {
39+
@Override
40+
@SuppressWarnings("unchecked")
41+
public <B> ContainedBean<B> getBean(
42+
Class<B> beanType,
43+
LifecycleOptions lifecycleOptions,
44+
BeanInstanceProducer fallbackProducer) {
45+
return () -> (B) ( beanType == DummyConnectionProvider.class ?
46+
dummyConnectionProvider : fallbackProducer.produceBeanInstance( beanType ) );
47+
}
48+
49+
@Override
50+
public <B> ContainedBean<B> getBean(
51+
String name,
52+
Class<B> beanType,
53+
LifecycleOptions lifecycleOptions,
54+
BeanInstanceProducer fallbackProducer) {
55+
return () -> (B) fallbackProducer.produceBeanInstance( beanType );
56+
}
57+
58+
@Override
59+
public void stop() {
60+
61+
}
62+
} );
63+
return settings;
64+
}
65+
66+
@Test
67+
public void testProviderFromBeanContainerInUse() {
68+
Map<String, Object> settings = createSettings();
69+
settings.putIfAbsent( CONNECTION_PROVIDER, DummyConnectionProvider.class.getName() );
70+
try ( ServiceRegistry serviceRegistry = ServiceRegistryUtil.serviceRegistryBuilder()
71+
.applySettings( settings ).build() ) {
72+
ConnectionProvider providerInUse = serviceRegistry.getService( ConnectionProvider.class );
73+
assertSame( dummyConnectionProvider, providerInUse );
74+
}
75+
}
76+
77+
public static class DummyConnectionProvider implements ConnectionProvider {
78+
79+
@Override
80+
public boolean isUnwrappableAs(Class<?> unwrapType) {
81+
return false;
82+
}
83+
84+
@Override
85+
public <T> T unwrap(Class<T> unwrapType) {
86+
return null;
87+
}
88+
89+
@Override
90+
public Connection getConnection() throws SQLException {
91+
return null;
92+
}
93+
94+
@Override
95+
public void closeConnection(Connection connection) throws SQLException {
96+
97+
}
98+
99+
@Override
100+
public boolean supportsAggressiveRelease() {
101+
return false;
102+
}
103+
};
104+
}

0 commit comments

Comments
 (0)