1

我正在尝试在 JTA 会话(服务器管理)中执行不相关的查询(other_table),以便在使用 JPA 将 bean EJB 持久化到 DB 之前进行一些验证。

这是我想做的(大约):

@PersistenceUnit(unitName="DynamicDatabase")
EntityManagerFactory emf;

@TransactionAttribute(TransactionAttributeType.REQUIRED)
private long nextEntryid() {
    em = emf.createEntityManager();
    Query query = em.createQuery("select t from OTHER_TABLE t");
    // do some validation and checking
    MyTable bean = new MyTable();
    em.persist(bean);
}

但是我不断收到服务器错误,它不允许与其他未持久化的数据库项进行交互:

org.apache.openjpa.persistence.ArgumentException:
An error occurred while parsing the query filter (query): The name "OTHER_TABLE" is not a recognized entity (...) Perhaps you meant MyTable, which is a close match.

<persistence-unit name="DynamicDatabase" transaction-type="JTA">
    <jta-data-source>jdbc/DB2DynamicConnection</jta-data-source>
    <class>jorge.java.dynamicdatabase.db.MyTable</class>
    </properties>
</persistence-unit>

问题是:在同一个 JPA DB 连接和 JTA 事务中查询/更改另一个表的正确方法是什么?

对此很陌生,请耐心等待我。在这方面工作了很长时间。

编辑:我不认为这是相关的,但仅供参考,我正在使用WebSphere Liberty Profile 8.5.5.4、JSDK 8u31、EclipseEE Luna 4.4.2 for Web Dev。打算将其添加到标签中。

4

2 回答 2

1

问题是您有一个引用实体的 @NamedQuery OTHER_TABLE,并且它不存在或未标记为实体(在 Java 类和 persistence.xml 中尝试)。

如果OtherTableJava 类不是实体并且它必须保持不变,那么您可以在 JPQL-queries 中使用构造函数

SELECT NEW com.domain.reports.MyReport(u.firstName, u.lastName, u.birthday) FROM User u

如果您需要编写普通的 SQL 查询,那么您可以使用本机查询来完成,因为它们在 JPA 规范中是已知的。

于 2015-03-19T13:50:41.683 回答
0

根据 Andrei 的建议,JPQL(Java Persistence Query Language)对对象而不是表进行操作。这意味着em.createQuery()不能用于通用数据库交互。

一般来说,要执行任何 SQL 语句(在容器管理的事务 JTA 内部),需要从实体管理器获取 DB 连接(它将返回持久性上下文单元 JPA)。

    // Get container's objects
    em = emf.createEntityManager();
    java.sql.Connection conn = em.unwrap(java.sql.Connection.class);

    // Run the query
    Statement sql = conn.createStatement();
    ResultSet rs = sql.executeQuery("select * from OTHER_TABLE");
    rs.next()
    (...)

    //Container-managed connection shouldn't be closed. 
    rs.close;
    sql.close;

请注意,unwrap调用适用于 JPA,但不适用于 Hibernate(在这一点上已经存在其他问题)。注意 SQL 语句使用的语言与select * from命名查询 JPQL不同select t from。异常处理也必须像往常一样使用} finally {子句进行控制。

这种方式将允许在服务器管理的事务中执行复杂的自定义语句,而无需使用 JAVA 实体,我终于可以睡觉了。

于 2015-03-20T10:46:12.627 回答