I need to use my own JDBC Connector and Connection. So I first tried to set up my own connector our own connector that inherits from JNDIConnector in the eclipselink.jdbc.connector property with reference to the following site.
hibernate - How to reference a custom 'ConnectionProvider' in EclipseLink? - Stack Overflow
package xxx.myPackage.MyPackage;
import org.eclipse.persistence.sessions.JNDIConnector;
import org.eclipse.persistence.sessions.Session;
import java.sql.Connection;
import javax.sql.DataSource;
import java.util.Properties;
public class MyConnector extends JNDIConnector {
public MyConnector() {
super();
setName("MyDataSourceName");
}
public MyConnector(DataSource dataSource) {
super(dataSource);
}
@Override
public Connection connect(Properties properties, Session session) {
Connection con = super.connect(properties, session);
// My proprietary process is implemented
// and new MyCustomConnection below.
return new MyCustomConnection(con);
}
}
<property name="eclipselink.jdbc.connector" value="xxx.myPackage.MyConnector"/>
However, this method did not work. Because this method seems to use EclipseLink's internal connection pool and not the AP server's connection pool. (As far as I can see from the log, the connect method is not called each time SQL is executed.)
About Connection Pools | EclipseLink 2.6.x Understanding EclipseLink
Question.1: Is there any way to use the AP server connection pool while using the "eclipselink.jdbc.connector” property?
So I then tried the eclipselink.session.customizer property. In the customizer class, we replaced the already configured connector with our own connector class, and then configured it to use the connection pool of the AP server.
package xxx.myPackage;
import org.eclipse.persistence.sessions.JNDIConnector;
import org.eclipse.persistence.sessions.Session;
public class MyEclipseLinkSessionCustomizer implements SessionCustomizer{
@Override
public void customize(Session session) throws Exception {
JNDIConnector jc = (JNDIConnector) session.getLogin().getConnector();
session.getLogin().setConnector(new MyConnector(getDataSource()));
// Configure EclipseLink to use the external connection pool just in case.
session.getLogin().setUsesExternalConnectionPooling(true);
}
}
<property name="eclipselink.session.customizer" value="xxx.myPackage.MyEclipseLinkSessionCustomizer"/>
This method apparently works well.
Question2: Is this method of use common? Are there any risks involved?
----- I have updated the following.-----
The following is a part of the EntityManagerSetupImpl#updateLogins(Map).
If it does not inherit JNDIConnector, it will be re-generated (even though I want to use my own connector). Conversely, if it inherits JNDIConnector, it will not be updated and will not be updated to use the external connection Pool. I do not understand the intent of this implementation. Why? eclipselink/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/EntityManagerSetupImpl.java at 2.7 · eclipse-ee4j/eclipselink (github.com)
// mainDatasource is guaranteed to be non null - TODO: No it is not, if they did not set one it is null, should raise error, not null-pointer.
if (!(login.getConnector() instanceof JNDIConnector)) {
JNDIConnector jndiConnector;
if (mainDatasource instanceof DataSourceImpl) {
//Bug5209363 Pass in the datasource name instead of the dummy datasource
jndiConnector = new JNDIConnector(((DataSourceImpl)mainDatasource).getName());
} else {
jndiConnector = new JNDIConnector(mainDatasource);
}
login.setConnector(jndiConnector);
String useInternalConnectionPool = getConfigPropertyAsStringLogDebug(PersistenceUnitProperties.CONNECTION_POOL_INTERNALLY_POOL_DATASOURCE, m, this.session);
if (!"true".equalsIgnoreCase(useInternalConnectionPool)){
login.setUsesExternalConnectionPooling(true);
}
}