如何通过Hibernate通过SSH隧道连接数据库

时间:2015-09-22 08:09:54

标签: java hibernate ssh jsch

我的数据库位于ssh隧道中,我使用JSch连接它。

这是我的Java代码:

static String sshHost, sshAccount, sshPassword;
static int sshPort = 22;
static int localPort = 3399, remotePort = 3306;
static String remoteHost = "localhost";

public static void main(String[] args) throws JSchException {
    Properties config = new Properties();
    config.put("StrictHostKeyChecking", "no");
    JSch jsch = new JSch();
    com.jcraft.jsch.Session jschSession  = jsch.getSession(sshAccount, sshHost, sshPort);
    jschSession.setPassword(sshPassword);
    jschSession.setConfig(config);

    System.out.println("Start Connecting " + sshHost + ":" + sshPort);
    jschSession.connect();
    int assinged_port = jschSession.setPortForwardingL(localPort,
            remoteHost, remotePort);

    System.out.println("localhost:" + assinged_port + " -> " + remoteHost + ":" + remotePort);

    System.out.println("Connect Hibernate");
    Configuration configuration = new Configuration().configure();
    StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
    SessionFactory factory = configuration.buildSessionFactory(builder.build());
    Session session = factory.openSession();
    Transaction tx = session.beginTransaction();

    System.out.println("Close Hibernate Connection");
    tx.commit();
    session.close();
    factory.close();

    System.out.println("Closing SSH Connection");
    session.disconnect();
}

这是我的Hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration >
    <session-factory name="java:hibernate/SessionFactory">
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.password">[Database password]</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3906/PM?characterEncoding=utf8</property>
        <property name="hibernate.connection.username">[Database User]</property>
        <property name="hibernate.connection.socketFactory">com.mysql.jdbc.NamedPipeSocketFactory</property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    </session-factory>
    <mapping class="db.User" />
</hibernate-configuration>

我已经使用herehere中的代码进行测试。因此,我确定SSH服务器,数据库帐户,密码,URL和端口的变量是正确的。

运行代码后,它给出了错误消息:

Exception in thread "main" org.hibernate.MappingException: invalid configuration
    at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:2160)
    at org.hibernate.cfg.Configuration.configure(Configuration.java:2077)
    at org.hibernate.cfg.Configuration.configure(Configuration.java:2056)
    at sshtest.hibernate_connect.main(hibernate_connect.java:41)
Caused by: org.xml.sax.SAXParseException; lineNumber: 15; columnNumber: 27; 元素類型 "hibernate-configuration" 的內容必須配對 "(session-factory,security?)"。
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.handleEndElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.endElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at org.dom4j.io.SAXReader.read(SAXReader.java:465)
    at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:2157)
    ... 3 more  

我不知道如何连接我的数据库。

09-23添加

现在我更改xml文件,如下所示(删除会话工厂中db.User&amp;“name”属性的映射):

<hibernate-configuration >
    <session-factory>
        ...
    </session-factory>
</hibernate-configuration>

我也使用Question 12737293给出的方式,所以我确定我的端口(3399)没有使用。

但是,它仍然给出了错误消息:

Cannot connect Hibernateorg.hibernate.exception.JDBCConnectionException: Error calling Driver#connect
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:132)
    at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator$1$1.convert(BasicConnectionCreator.java:118)
    at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.convertSqlException(BasicConnectionCreator.java:140)
    at org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator.makeConnection(DriverConnectionCreator.java:58)
    at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.createConnection(BasicConnectionCreator.java:75)
    at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.configure(DriverManagerConnectionProviderImpl.java:106)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206)
    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.buildJdbcConnectionAccess(JdbcServicesImpl.java:260)
    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:94)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206)
    at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1887)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1845)
    at sshtest.hibernate_connect.main(hibernate_connect.java:46)
Caused by: com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception: 

** BEGIN NESTED EXCEPTION ** 

java.io.FileNotFoundException
MESSAGE: \\.\pipe\MySQL (系統找不到指定的檔案。)

STACKTRACE:

java.io.FileNotFoundException: \\.\pipe\MySQL (系統找不到指定的檔案。)
    at java.io.RandomAccessFile.open0(Native Method)
    at java.io.RandomAccessFile.open(Unknown Source)
    at java.io.RandomAccessFile.<init>(Unknown Source)
    at java.io.RandomAccessFile.<init>(Unknown Source)
    at com.mysql.jdbc.NamedPipeSocketFactory$NamedPipeSocket.<init>(NamedPipeSocketFactory.java:57)
    at com.mysql.jdbc.NamedPipeSocketFactory.connect(NamedPipeSocketFactory.java:215)
    at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:271)
    at com.mysql.jdbc.Connection.createNewIO(Connection.java:2771)
    at com.mysql.jdbc.Connection.<init>(Connection.java:1555)
    at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
    at org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator.makeConnection(DriverConnectionCreator.java:55)
    at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.createConnection(BasicConnectionCreator.java:75)
    at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.configure(DriverManagerConnectionProviderImpl.java:106)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206)
    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.buildJdbcConnectionAccess(JdbcServicesImpl.java:260)
    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:94)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206)
    at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1887)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1845)
    at sshtest.hibernate_connect.main(hibernate_connect.java:46)


** END NESTED EXCEPTION **



Last packet sent to the server was 1 ms ago.
    at com.mysql.jdbc.Connection.createNewIO(Connection.java:2847)
    at com.mysql.jdbc.Connection.<init>(Connection.java:1555)
    at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
    at org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator.makeConnection(DriverConnectionCreator.java:55)
    ... 13 more

1 个答案:

答案 0 :(得分:-1)

您遇到此问题,因为您已将<mapping>标记保留在<session-factory>标记之外。 你hibernate.cfg.xml看起来应该是

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration >
    <session-factory name="java:hibernate/SessionFactory">
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.password">password</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3906/PM?characterEncoding=utf8</property>
        <property name="hibernate.connection.username">[Database User]</property>
        <property name="hibernate.connection.socketFactory">com.mysql.jdbc.NamedPipeSocketFactory</property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <mapping class="db.User" />
    </session-factory>

</hibernate-configuration>