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

时间:2015-03-15 20:18:48

标签: jdbc jta websphere-liberty jpa-2.1 jdk6

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

这是我想做的事(aprox):

@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 。要将其添加到标签。

2 个答案:

答案 0 :(得分:1)

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

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

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

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

答案 1 :(得分:0)

根据Andrei的建议,JPQL(Java持久性查询语言)在对象上运行,而不是在表上运行。这意味着em.createQuery()无法用于通用数据库交互。

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