调用事务方法Play Java JPA Hibernate

时间:2016-11-28 07:56:09

标签: java hibernate jpa playframework playframework-2.5

我有2个数据库,一个是mysql,另一个是postgree。 我试图从mysql事务方法中获取postgree数据。

@Transactional(value = "pg")
    public List<String> getSubordinate(){
        Query q1 = JPA.em().createNativeQuery("select vrs.subordinate_number, vrs.superior_number\n" +
                "from view_reporting_structure vrs\n" +
                "where vrs.superior_number = :personel_number");
        q1.setParameter("personel_number","524261");
        List<String> me = q1.getResultList();
        return me;
    }
}

来自另一种方法

@Transactional
public Result getOpenRequestList(){
    Subordinate subordinate = new Subordinate();
    List<String> subordinateData = subordinate.getSubordinate();
    ....
}

我收到了错误

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'db_hcm.view_reporting_structure' doesn't exist

所以我的Postgre方法被认为是mySQL事务,这是mySQL数据库中不存在的视图。如何通过1种方法从不同的存储单元获取数据?

1 个答案:

答案 0 :(得分:1)

我从来没有这样做过(不同的数据库),但我猜以下可能会有效。

例如,您在application.conf中有以下数据源定义:

# MySql
db.mysql.driver=com.mysql.jdbc.Driver
... the rest of setting for db.mysql

# H2
db.postgre.driver=org.postgresql.Driver
... the rest of setting for db.postgre

不使用@Transactional注释,而是显式管理事务并使用JPA withTransaction API:

private static final String MYSQL_DB = "mysql";
private static final String POSTGRE_DB = "postgre";

public List<String> getSubordinate() {
    JPA.withTransaction(MYSQL_DB, true/* this is read-only flag*/,
    () -> {
        Query q1 = JPA.em().createNativeQuery("select vrs.subordinate_number, vrs.superior_number\n" +
            "from view_reporting_structure vrs\n" +
            "where vrs.superior_number = :personel_number");
        q1.setParameter("personel_number","524261");
        List<String> me = q1.getResultList();
        return me;
    }
}

public Result getOpenRequestList(){
    JPA.withTransaction(POSTGRE_DB, true/* this is read-only flag*/,
    () -> {
        Subordinate subordinate = new Subordinate();
        List<String> subordinateData = subordinate.getSubordinate();
        ....
    }
}

注意:我更喜欢使用withTransaction,因为它可以更好地控制不愉快的流量。你应该用try-catch包装调用。如果JPA在提交时抛出运行时异常,则可以进行适当的错误处理。如果使用@Transactional注释,则在控制器完成后进行提交,您无法处理错误。