Java mysql主/从复制问题:无法创建PoolableConnectionFactory

Java mysql主/从复制问题:无法创建PoolableConnectionFactory,java,mysql,jdbc,openjpa,master-slave,Java,Mysql,Jdbc,Openjpa,Master Slave,我已经花了很多时间,但还是想不出来。我知道,如果我使用BasicDataSource,那么配置需要在openjpa.ConnectionProperties属性中传递。openjpa.ConnectionProperties是以逗号(,)分隔的属性,映射到实例。现在还需要逗号(,)分隔格式的主机。因此,我不知道如何使用MySQL复制创建DataSource* 我正在尝试使用openjpa设置主/从数据库,但在从EntityManager工厂创建createEntityManager()时失败,出

我已经花了很多时间,但还是想不出来。我知道,如果我使用
BasicDataSource
,那么配置需要在
openjpa.ConnectionProperties
属性中传递。
openjpa.ConnectionProperties
是以逗号(,)分隔的属性,映射到实例。现在还需要逗号(,)分隔格式的主机。因此,我不知道如何使用
MySQL复制创建
DataSource
*

我正在尝试使用openjpa设置主/从数据库,但在从
EntityManager工厂创建
createEntityManager()
时失败,出现以下异常

代码如下:

String driver ="com.mysql.jdbc.ReplicationDriver";
String url = "jdbc:mysql:replication://master:3306,slave:3306/db";
String user = "abc";
String password = "123";
String connProps = "DriverClassName={0},Url={1},Username={2},Password={3}";

public void method() {
    connProps = MessageFormat.format(connProps, driver, url, user, password);
    Properties props = new Properties();
    props.setProperty("openjpa.ConnectionProperties", connProps);
    props.setProperty("openjpa.ConnectionDriverName", "org.apache.commons.dbcp.BasicDataSource");
    EntityManagerFactory factory = Persistence.createEntityManagerFactory("mysql", props);
    EntityManager manager = factory.createEntityManager();
}
我遇到以下异常:

Exception in thread "main" <openjpa-2.4.1-r422266:1730418 fatal general error> org.apache.openjpa.persistence.PersistenceException: Cannot create PoolableConnectionFactory (Must specify at least one slave host to connect to for master/slave replication load-balancing functionality)
    at org.apache.openjpa.jdbc.sql.DBDictionaryFactory.newDBDictionary(DBDictionaryFactory.java:106)
    at org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl.getDBDictionaryInstance(JDBCConfigurationImpl.java:603)
    at org.apache.openjpa.jdbc.meta.MappingRepository.endConfiguration(MappingRepository.java:1520)
    at org.apache.openjpa.lib.conf.Configurations.configureInstance(Configurations.java:533)
    at org.apache.openjpa.lib.conf.Configurations.configureInstance(Configurations.java:458)
    at org.apache.openjpa.lib.conf.PluginValue.instantiate(PluginValue.java:121)
    at org.apache.openjpa.conf.MetaDataRepositoryValue.instantiate(MetaDataRepositoryValue.java:68)
    at org.apache.openjpa.lib.conf.ObjectValue.instantiate(ObjectValue.java:83)
    at org.apache.openjpa.conf.OpenJPAConfigurationImpl.newMetaDataRepositoryInstance(OpenJPAConfigurationImpl.java:967)
    at org.apache.openjpa.conf.OpenJPAConfigurationImpl.getMetaDataRepositoryInstance(OpenJPAConfigurationImpl.java:958)
    at org.apache.openjpa.kernel.AbstractBrokerFactory.makeReadOnly(AbstractBrokerFactory.java:642)
    at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:202)
    at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:154)
    at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:226)
    at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:153)
    at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:59)
    at ExampleJPA.method(ExampleJPA.java:22)
    at ExampleJPA.main(ExampleJPA.java:27)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (Must specify at least one slave host to connect to for master/slave replication load-balancing functionality)
    at org.apache.commons.dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1549)
    at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1388)
    at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
    at org.apache.openjpa.lib.jdbc.DelegatingDataSource.getConnection(DelegatingDataSource.java:110)
    at org.apache.openjpa.lib.jdbc.DecoratingDataSource.getConnection(DecoratingDataSource.java:86)
    at org.apache.openjpa.jdbc.sql.DBDictionaryFactory.newDBDictionary(DBDictionaryFactory.java:90)
    ... 22 more
Caused by: java.sql.SQLException: Must specify at least one slave host to connect to for master/slave replication load-balancing functionality
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:957)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:896)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:885)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:860)
    at com.mysql.jdbc.NonRegisteringDriver.connectReplicationConnection(NonRegisteringDriver.java:414)
    at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:313)
    at org.apache.commons.dbcp.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:38)
    at org.apache.commons.dbcp.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:582)
    at org.apache.commons.dbcp.BasicDataSource.validateConnectionFactory(BasicDataSource.java:1556)
    at org.apache.commons.dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1545)
    ... 27 more
线程“main”org.apache.openjpa.persistence.PersistenceException中的异常:无法创建PoolableConnectionFactory(必须指定至少一个要连接的从属主机以实现主/从属复制负载平衡功能)
位于org.apache.openjpa.jdbc.sql.DBDictionaryFactory.newDBDictionary(DBDictionaryFactory.java:106)
位于org.apache.openjpa.jdbc.conf.jdbconfigurationmpl.getDBDictionaryInstance(jdbconfigurationmpl.java:603)
位于org.apache.openjpa.jdbc.meta.MappingRepository.endConfiguration(MappingRepository.java:1520)
位于org.apache.openjpa.lib.conf.Configurations.configureInstance(Configurations.java:533)
位于org.apache.openjpa.lib.conf.Configurations.configureInstance(Configurations.java:458)
位于org.apache.openjpa.lib.conf.PluginValue.instantiate(PluginValue.java:121)
位于org.apache.openjpa.conf.MetaDataRepositoryValue.instantiate(MetaDataRepositoryValue.java:68)
在org.apache.openjpa.lib.conf.ObjectValue.instantiate(ObjectValue.java:83)上
位于org.apache.openjpa.conf.OpenJPAConfigurationImpl.newMetaDataRepositoryInstance(OpenJPAConfigurationImpl.java:967)
位于org.apache.openjpa.conf.OpenJPAConfigurationImpl.getMetaDataRepositoryInstance(OpenJPAConfigurationImpl.java:958)
位于org.apache.openjpa.kernel.AbstractBrokerFactory.makeReadOnly(AbstractBrokerFactory.java:642)
位于org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:202)
位于org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:154)
位于org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:226)
位于org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:153)
位于org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:59)
方法(ExampleJPA.java:22)
在ExampleJPA.main(ExampleJPA.java:27)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)中
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于java.lang.reflect.Method.invoke(Method.java:606)
位于com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
原因:org.apache.commons.dbcp.SQLNestedException:无法创建PoolableConnectionFactory(必须指定至少一个要连接的从属主机以实现主/从属复制负载平衡功能)
位于org.apache.commons.dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1549)
位于org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1388)
位于org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
位于org.apache.openjpa.lib.jdbc.DelegatingDataSource.getConnection(DelegatingDataSource.java:110)
位于org.apache.openjpa.lib.jdbc.DecoratingDataSource.getConnection(DecoratingDataSource.java:86)
位于org.apache.openjpa.jdbc.sql.DBDictionaryFactory.newDBDictionary(DBDictionaryFactory.java:90)
... 还有22个
原因:java.sql.SQLException:必须指定至少一个要连接到的从属主机以实现主/从属复制负载平衡功能
位于com.mysql.jdbc.SQLError.createSQLException(SQLError.java:957)
位于com.mysql.jdbc.SQLError.createSQLException(SQLError.java:896)
位于com.mysql.jdbc.SQLError.createSQLException(SQLError.java:885)
位于com.mysql.jdbc.SQLError.createSQLException(SQLError.java:860)
位于com.mysql.jdbc.NonRegisteringDriver.connectReplicationConnection(NonRegisteringDriver.java:414)
位于com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:313)
位于org.apache.commons.dbcp.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:38)
位于org.apache.commons.dbcp.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:582)
位于org.apache.commons.dbcp.BasicDataSource.validateConnectionFactory(BasicDataSource.java:1556)
位于org.apache.commons.dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1545)
... 还有27个

数据库的主从设置似乎工作正常。我已经通过telnet检查了从机与主机之间的连接。

传递给MySQL驱动程序的JDBC URL不是您所认为的。 MySQL驱动程序正在尝试解析URL,并使用“
”、“
令牌”将其拆分

    if ((hostStuff != null) && (hostStuff.trim().length() > 0)) {
        List<String> hosts = StringUtils.split(hostStuff, ",", ALLOWED_QUOTES, ALLOWED_QUOTES, false);
if((hostStuff!=null)和&(hostStuff.trim().length()>0)){
List hosts=StringUtils.split(hostststuff,,,允许的\u引号,允许的\u引号,false);
但它无法找到多个,因此会产生错误:

    int numHosts = Integer.parseInt(parsedProps.getProperty(NUM_HOSTS_PROPERTY_KEY));

    if (numHosts < 2) {
        throw SQLError.createSQLException("Must specify at least one slave host to connect to for master/slave replication load-balancing functionality",
                SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE, null);
    }
int numHosts=Integer.parseInt(parsedProps.getProperty(NUM_HOSTS_PROPERTY_KEY));
if(numHosts<2){
throw SQLError.createSQLException(“必须指定至少一个要连接的从属主机以实现主/从属复制负载平衡功能”,
SQLError.SQL\u STATE\u连接无效\u属性,null);
}
JDBCURL很可能是由DBCP或OpenJPA修改/破坏的

链接
props.setProperty("openjpa.ConnectionDriverName", "org.apache.commons.dbcp.BasicDataSource");
props.setProperty("openjpa.ConnectionUserName", user);
props.setProperty("openjpa.ConnectionPassword", password);
props.setProperty("openjpa.ConnectionURL", url);
props.setProperty("openjpa.ConnectionProperties", connProps);