【问题标题】:Java Hibernate Check MySQL Replication is in syncJava Hibernate 检查 MySQL 复制是否同步
【发布时间】:2013-05-28 09:25:31
【问题描述】:

通常我们通过控制台命令检查从属服务器上的复制是否正常

SHOW SLAVE STATUS \G;

我想将此功能合并到一个 servlet 报告应用程序中。 但是,hibernate 似乎不允许这样做:

createSQLQuery("SHOW SLAVE STATUS");
...executing query...
java.lang.UnsupportedOperationException: not yet implemented for SQL queries

我确信使用本机 JDBC 可以实现这一点,但也许有更好的方法? 环境:Linux 2.6.18、Tomcat 6/7、Hibernate 3.4、Java 1.6、MySQL 5 注意:我对在 master 上插入时间戳的解决方案不感兴趣。

【问题讨论】:

  • 你在哪里得到这个异常
  • 参考此链接您可能会了解您的问题Link。还可以参考此链接中的其他链接
  • @PSR java.lang.UnsupportedOperationException:尚未在 org.hibernate.impl.SQLQueryImpl.getReturnTypes(SQLQueryImpl.java:249) com.xxxxxx.servlet.doGet(AbstractServlet.java) 上实现 SQL 查询:516)

标签: mysql hibernate


【解决方案1】:

当你使用createSQLQuery 运行原生SQL 查询时,你必须告诉Hibernate how to convert the results into Java objects。在您的情况下,最简单的方法是添加

query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);

在执行查询之前。 (如果查询返回已经映射的实体,您可以使用addEntity()。)

【讨论】:

  • 如果这不起作用,那么您需要提供有关您正在做什么以及导致异常的原因的更多信息。 ...executing query... 信息量不大。
  • 有人编辑了我的问题 - 如果他们减少了信息量,我们深表歉意。
【解决方案2】:

我还没有努力使这项工作与 Hibernate 一起工作,但如果失败,您仍然可以使用良好的老式 JDBC 连接:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Test {

    static final String DB_ADDRESS = "localhost";
    static final String DB_NAME = "mysql";
    static final String DB_USER = "root";

    public static void main (String[] args) {
        // get password
        String password = "";
        if (args!=null && args.length>0) {
            password = args[0];
        }

        try {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
        } catch (Exception ex) {
            // handle the error
            System.out.println("Driver issue: " + ex.getMessage());
            System.out.println("Driver issue: " + ex.getClass().toString());
        }
        // connect to database
        try {
            Connection conn = 
               DriverManager.getConnection("jdbc:mysql://"+DB_ADDRESS+"/"+DB_NAME+"?autoReconnect=true",DB_USER,password);

            // Do something with the Connection
            System.out.println("Connection: " + conn);
            Statement stmt = conn.createStatement();


            ResultSet RS = stmt.executeQuery("SHOW TABLES");
            while (RS.next()) {
                System.out.println("table: '" + RS.getString(1) + "'");
            }

            // disconnect from database
            conn.close();
            stmt.close();

        } catch (SQLException ex) {
            // handle any errors
            System.out.println("SQLException: " + ex.getMessage());
            System.out.println("SQLState: " + ex.getSQLState());
            System.out.println("VendorError: " + ex.getErrorCode());
        }
    }
}

这将返回:

Connection: com.mysql.jdbc.JDBC4Connection@528acf6e
table: 'columns_priv'
table: 'db'
table: 'event'
table: 'func'
table: 'general_log'
table: 'help_category'
table: 'help_keyword'
table: 'help_relation'
table: 'help_topic'
table: 'host'
table: 'ndb_binlog_index'
table: 'plugin'
table: 'proc'
table: 'procs_priv'
table: 'proxies_priv'
table: 'servers'
table: 'slow_log'
table: 'tables_priv'
table: 'time_zone'
table: 'time_zone_leap_second'
table: 'time_zone_name'
table: 'time_zone_transition'
table: 'time_zone_transition_type'
table: 'user'

不用说,关键是确保您的用户有足够的权限。

【讨论】:

    【解决方案3】:

    这对我有用..

    SQLQuery query =session.createSQLQuery("show slave status");
    ArrayList<Object[]> results = (ArrayList<Object[]>)query.list();
    //there is only one row returned
    Object [] result =  results.get(0);
    //Seconds Behind Master should always be the last value in the row.
    String secondsBehindMaster = ""+result[result.length-1];
    

    确保 DB 用户具有 REPLICATION CLIENT 权限以进行此查询。

    GRANT REPLICATION CLIENT ON *.* TO 'db_user'@'db_server' IDENTIFIED BY 'db_password';
    

    【讨论】:

    • 看起来很简单。我认为权限也是一个因素。它现在完美运行。谢谢。
    【解决方案4】:

    正如UnsupportedOperationException 异常的消息所暗示的那样,getReturnTypes() 不是由createSQLQuery() 返回的SQLQuery 对象实现的。

    顺便说一句,您问题的措辞具有误导性,您在调用createSQLQuery() 时没有收到异常,但在几行之后。

    当您发出本机 SQL 时,您将检索行作为通用 Object[] 的列表(除非您明确地为 Hibernate 提供映射)。通常,这些类型将在编译时知道。

    更多信息请参见here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-29
      • 2014-09-04
      • 2015-05-13
      相关资源
      最近更新 更多