2015-09-22 105 views
-1

我的數據庫位於ssh隧道中,我使用JSch來連接它。如何通過休眠方式通過SSH隧道連接數據庫

這裏是我的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 &會話工廠 「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 
+0

你有一個XML解析錯誤。我懷疑這與你的SSH隧道有什麼關係。 –

+0

嗯......當我使用不在ssh隧道中的數據庫時,我使用相同的xml代碼,它不會給出任何錯誤。因此,如果是xml的問題,我不知道應該在哪裏更改 – Shiyou

回答

-1

你面臨這樣的問題,因爲你已經保持<session-factory>標籤之外<mapping>標籤。 你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> 
+0

是的,移動映射並移除屬性'name =「java:hibernate/SessionFactory」'它可以運行hibernate代碼。然而,它仍然有錯誤(我已經把新問題放入我的問題)。 – Shiyou

+0

請發佈您的完整棧跟蹤 –

+0

爲什麼downvote?這是上一個問題的解決方案(在下次更新之前) –