-2

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);
            }
        }
  • Please provide enough code so others can better understand or reproduce the problem. – Community Aug 26 '23 at 21:22
  • Ok I add example code.I am not familiar with EclipseLink so I do not know why it does not work with "eclipseselink.jdbc.connector". Also, I'm not sure if I can do the above with SessionCustomizer, so please let me know. – UKnowWhatUKnow Aug 27 '23 at 08:29
  • Yes, using a customizer is what you should be doing when you want very specific behavior - Risks are that someone tries use this code in a spot where they don't want your JNDIConnector implementation and don't notice this code. You might be able to get the connector property to work, but I've never used it -you'd have to debug into EclipseLink code to see if you are missing some other property or setting that causes it to use internal pooling (the default) instead of external pooling if that is what you've configured in persistence.xml – Chris Aug 28 '23 at 13:53
  • Thanks for the reply. It makes me understood that Customizer should be used in limited cases. The risks you have pointed out are plausible and I will check with the other members to see if this approach is acceptable.On the other hand, as far as I can see the code (EntityManagerSetupImpl#updateLogins),the property "eclipseselink.jdbc.connector" seemed to me to assume the use of internal pooling (default). In that case, this idea is not a solution, so I will investigate this further. – UKnowWhatUKnow Aug 29 '23 at 09:09

0 Answers0