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 实体 ,我终于可以睡觉了。
我正在尝试在 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 实体 ,我终于可以睡觉了。