JPA 服务器管理的会话中的自定义查询

Custom query within JPA server-managed session

我正在尝试在 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 数据库连接和 JTA 事务中 query/alter 另一个 table 的正确方法是什么?

新手,请耐心等待。一直致力于此。

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

问题是您有一个引用实体 OTHER_TABLE 的 @NamedQuery,但该实体不存在或未标记为实体(尝试 Java class和 persistence.xml).

如果 OtherTable Java class 不是实体并且必须保持实体状态,那么您可以使用 Constructors in JPQL-queries:

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

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

根据 Andrei 的建议,JPQL(Java 持久性查询语言)对对象而非表进行操作。这意味着 em.createQuery() 不能用于通用数据库交互。

一般来说(在容器管理的事务 JTA 中)要执行任何 SQL 语句,有必要从实体管理器获取 DB 连接(它将 return 持久性上下文单元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 实体 ,我终于可以睡觉了。