Здравствуйте. Возникла проблема - клиент H2 приложения не видит схему на сервере. Ошибка:
Schema "MY_SERVERDB" not found; SQL statement: SELECT userid, username FROM my_serverdb.MYUSERS
Соль в том, что я с клиента логинюсь пользователем, созданным с сервера. И если указать неправильный пароль, сервер не пускает. Разве пользователи бд не хранятся в этой же бд?
Код сервера:
private String path = "jdbc:h2:./h2databases/my_serverdb";
private String settings = ";CIPHER=AES;AUTO_SERVER=TRUE;MULTI_THREADED=1";
private String user = "serveradmin";
private String password = "filepassword adminpassword";
public H2Server() {
try {
Class.forName("org.h2.Driver");
} catch (ClassNotFoundException e) {
System.out.println(e);
}
System.out.println(":: H2 server side ::");
// starting the TCP Server
Server server=null;
Connection connection=null;
Statement statement=null;
ResultSet resultSet=null;
String sql=null;
try {
server = Server.createTcpServer("-tcpAllowOthers", "-webAllowOthers",
"-pgAllowOthers").start();
connection = DriverManager.getConnection(path+settings, user, password);
statement=connection.createStatement();
System.out.println("Port: "+server.getPort());
System.out.println("URL: "+server.getURL());
System.out.println("Status: "+server.getStatus());
sql = "CREATE TABLE IF NOT EXISTS MYUSERS("+
"userid int, username varchar(255),"+
"PRIMARY KEY(userid) )";
statement.execute(sql);
sql = "INSERT INTO MYUSERS (userid,username) VALUES (1,'denis')";
statement.execute(sql);
sql = "INSERT INTO MYUSERS (userid,username) VALUES (2,'fil')";
statement.execute(sql);
System.out.println(connection.getCatalog());
resultSet = statement.executeQuery("SELECT userid, username FROM MYUSERS");
while (resultSet.next()) {
String userid = resultSet.getString("userid");
String username = resultSet.getString("username");
System.out.println(userid+" "+username);
}
/*
DatabaseMetaData meta = connection.getMetaData();
ResultSet rs = meta.getTables("./serverdata", null,"%", null);
System.out.println("tables list:");
while (rs.next())
{
System.out.println(rs.getString(3));
}*/
// makes new user
sql = "CREATE USER MARY PASSWORD 'Marypassword'";
statement.execute(sql);
// gives mary rights only to read
sql = "GRANT SELECT ON MYUSERS TO MARY";
// sql = "GRANT ALTER ANY SCHEMA TO MARY";
System.out.println(
statement.execute(sql)
);
server.start();
Код клиента:
private String path = "jdbc:h2:tcp://localhost/~/h2databases/my_serverdb";
private String user = "MARY";
private String password = "Marypassword";
public H2Client() {
try {
Class.forName("org.h2.Driver");
} catch (ClassNotFoundException e){
System.out.println(e);
}
System.out.println(":: H2 client side ::");
Connection connection=null;
Statement statement=null;
ResultSet resultSet=null;
String sql=null;
try {
connection = DriverManager.getConnection(path, user, password);
statement=connection.createStatement();
System.out.println(connection.getCatalog());
resultSet = statement.executeQuery("SELECT userid, username FROM my_serverdb.MYUSERS");
while (resultSet.next()) {
String userid = resultSet.getString("userid");
String username = resultSet.getString("username");
System.out.println(userid+" "+username);
}
(вырезал лишние куски, которые не нужны для проблемы)
Все оказалось гораздо банальнее:
1. Используйте одну строку подключения: jdbc:h2:tcp://localhost/~/h2databases/my_serverdb
2. Разберитесь с настройками: private String settings = ";CIPHER=AES;AUTO_SERVER=TRUE;MULTI_THREADED=1"; и аргументами сервера, так как убрав их все заработало.
3. Я надеюсь, что в рабочем коде вы закрываете подключения.
Пару советов:
4. У Вас немного нарушена логика:
- Запуск сервера - это запуск сервера и создание таблиц ни как не связано с ним
- Вынесите создание таблиц и пользователей отдельно
- Не делайте запуск и работу с сервером в конструкторе
Итоговый код, который у меня заработал, хоть и вырвиглаз ))
Сервер:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.concurrent.CountDownLatch;
import java.util.logging.Logger;
import org.h2.tools.Server;
/**
*
* @author ezhov_da
*/
public class H2DbTest
{
private static final Logger LOG = Logger.getLogger(H2DbTest.class.getName());
private String path = "jdbc:h2:tcp://localhost/~/h2databases/my_serverdb";
private String settings = ";CIPHER=AES;AUTO_SERVER=TRUE;MULTI_THREADED=1";
private String user = "serveradmin";
private String password = "filepassword adminpassword";
private Server server;
private CountDownLatch countDownLatch = new CountDownLatch(1);
public H2DbTest()
{
Thread thread = new Thread()
{
@Override
public void run()
{
try
{
System.out.println(":: H2 server side ::");
// starting the TCP Server
server = Server
.createTcpServer(/*
* "-tcpAllowOthers",
* "-webAllowOthers",
* "-pgAllowOthers" */).start();
countDownLatch.countDown();
} catch (SQLException ex)
{
Logger.getLogger(H2DbTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
thread.start();
try
{
countDownLatch.await();
} catch (InterruptedException ex)
{
Logger.getLogger(H2DbTest.class.getName()).log(Level.SEVERE, null, ex);
}
try
{
Class.forName("org.h2.Driver");
} catch (ClassNotFoundException e)
{
System.out.println(e);
}
Statement statement = null;
ResultSet resultSet = null;
String sql = null;
try (Connection connection = DriverManager.getConnection(path/* + settings */, user, password);)
{
statement = connection.createStatement();
System.out.println("Port: " + server.getPort());
System.out.println("URL: " + server.getURL());
System.out.println("Status: " + server.getStatus());
sql = "CREATE TABLE IF NOT EXISTS MYUSERS("
+ "userid int, username varchar(255),"
+ "PRIMARY KEY(userid) )";
statement.execute(sql);
sql = "INSERT INTO MYUSERS (userid,username) VALUES (1,'denis')";
statement.execute(sql);
sql = "INSERT INTO MYUSERS (userid,username) VALUES (2,'fil')";
statement.execute(sql);
System.out.println(connection.getCatalog());
resultSet = statement.executeQuery("SELECT userid, username FROM MYUSERS");
while (resultSet.next())
{
String userid = resultSet.getString("userid");
String username = resultSet.getString("username");
System.out.println(userid + " " + username);
}
/*
* DatabaseMetaData meta = connection.getMetaData();
* ResultSet rs = meta.getTables("./serverdata", null,"%", null);
* System.out.println("tables list:");
* while (rs.next())
* {
* System.out.println(rs.getString(3));
* } */
// makes new user
sql = "CREATE USER MARY PASSWORD 'Marypassword'";
statement.execute(sql);
// gives mary rights only to read
sql = "GRANT SELECT ON MYUSERS TO MARY";
// sql = "GRANT ALTER ANY SCHEMA TO MARY";
System.out.println(
statement.execute(sql)
);
} catch (Exception e)
{
LOG.log(Level.ALL, "f", e);
System.out.println(e.getMessage());
}
while (true)
{
}
}
public static void main(String[] args)
{
H2DbTest h2DbTest = new H2DbTest();
}
}
Клиент:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author ezhov_da
*/
public class Client
{
private static final Logger LOG = Logger.getLogger(Client.class.getName());
private String path = "jdbc:h2:tcp://localhost/~/h2databases/my_serverdb";
private String user = "MARY";
private String password = "Marypassword";
public Client()
{
try
{
Class.forName("org.h2.Driver");
} catch (ClassNotFoundException e)
{
System.out.println(e);
}
System.out.println(":: H2 client side ::");
Statement statement = null;
ResultSet resultSet = null;
String sql = null;
try (Connection connection = DriverManager.getConnection(path, user, password);)
{
statement = connection.createStatement();
System.out.println(connection.getCatalog());
resultSet = statement.executeQuery("SELECT userid, username FROM MYUSERS");
while (resultSet.next())
{
String userid = resultSet.getString("userid");
String username = resultSet.getString("username");
System.out.println(userid + " " + username);
}
} catch (Exception e)
{
LOG.log(Level.ALL, "f", e);
System.out.println(e.getMessage());
}
}
public static void main(String[] args)
{
Client client = new Client();
}
}
Сборка персонального компьютера от Artline: умный выбор для современных пользователей