EntityManager em = getEntityManager();
EntityTransaction etx = em.getTransaction();
etx.begin();
Query query = em.createNamedQuery("login_procedure").setParameter("param1","user").setParameter("param2", "pw");
Integer result = 23;
try {
System.out.println("query = " + query.getSingleResult());
} catch (Exception e) {
result = null;
e.printStackTrace();
}
etx.commit();
em.close();
...执行此代码我得
[EL警告]:2011-02-10 17:32:16.846 - UnitOfWork(1267140342) - 例外情况 [EclipseLink-4002](Eclipse 持久性服务 - 1.2.0.v20091016-r5565):org.eclipse.persistence.exceptions.DatabaseException 内部异常: org.firebirdsql.jdbc.FBSQLException: GDS例外。 335544569.动态SQL 错误SQL错误代码= -104令牌 未知 - 第1行,第36栏 =错误代码:335544569呼叫:EXECUTE PROCEDURE LOGIN_PROCEDURE(USER_NAME = ?,USER_PASSWORD =?)bind => [用户, pw]查询: DataReadQuery(name =“login_procedure”)
-104 SQL错误通常表示SQL语法错误。
在调用query.getSingleResult()之前,所有内容都会被处理,没有任何错误。调用query.getResultList()不会改变任何东西。我已经尝试了几个1.x和2.x EclipseLink版本。 Firebird DB版本为2.1。
JPA2声明是:
@Entity
@NamedStoredProcedureQuery(
name = "login_procedure",
resultClass = void.class,
procedureName = "LOGIN_PROCEDURE",
returnsResultSet = false,
parameters = {
@StoredProcedureParameter(queryParameter = "param1", name = "USER_NAME", direction = Direction.IN, type = String.class),
@StoredProcedureParameter(queryParameter = "param2", name = "USER_PASSWORD", direction = Direction.IN, type = String.class)
}
)
@Table(name = "USERS")
public class Login implements Serializable {
@Id
private Long id;
}
更新: 在稍微修改一下之后,我相信EclipseLink实现中可能存在错误,因为 EXECUTE PROCEDURE LOGIN_PROCEDURE(USER_NAME =?,USER_PASSWORD =?)对于调用过程而言不是有效的Firebird 2.1语法。 / p>
答案 0 :(得分:1)
通过指定name =“USER_NAME”,您使用“USER_NAME =?”制作Eclipselink语法而不是仅传入未命名的参数。尝试删除名称定义。
答案 1 :(得分:0)
受this post的启发,我找到了解决方案/解决方法:
public class JPATest {
final Session session;
JPATest() {
final String DATABASE_USERNAME = "SYSDBA";
final String DATABASE_PASSWORD = "masterkey";
final String DATABASE_URL = "jdbc:firebirdsql:dbServer/3050:e:/my/db.fdb";
final String DATABASE_DRIVER = "org.firebirdsql.jdbc.FBDriver";
final DatabaseLogin login = new DatabaseLogin();
login.setUserName(DATABASE_USERNAME);
login.setPassword(DATABASE_PASSWORD);
login.setConnectionString(DATABASE_URL);
login.setDriverClassName(DATABASE_DRIVER);
login.setDatasourcePlatform(new FirebirdPlatform());
login.bindAllParameters();
final Project project = new Project(login);
session = project.createDatabaseSession();
session.setLogLevel(SessionLog.FINE);
((DatabaseSession) session).login();
}
public static void main(String[] args) {
final JPATest jpaTest = new JPATest();
jpaTest.run();
}
protected void run() {
testProcCursor();
}
/*
* Run Proc with scalar input and cursor output
*/
@SuppressWarnings("unchecked")
private void testProcCursor() {
final StoredProcedureCall call = new StoredProcedureCall();
call.setProcedureName("LOGIN");
call.addUnamedArgument("USER_NAME"); // .addNamedArgument doesn't work
call.addUnamedArgument("USER_PASSWORD");
final DataReadQuery query = new DataReadQuery();
query.setCall(call);
query.addArgument("USER_NAME");
query.addArgument("USER_PASSWORD");
final List<String> queryArgs = new ArrayList<String>();
queryArgs.add("onlinetester");
queryArgs.add("test");
final List outList = (List) session.executeQuery(query, queryArgs);
final ListIterator<DatabaseRecord> listIterator = ((List<DatabaseRecord>) outList).listIterator();
while (listIterator.hasNext()) {
final DatabaseRecord databaseRecord = listIterator.next();
System.out.println("Value -->" + databaseRecord.getValues());
}
}
}
在我的特定配置中不支持显然命名的参数,但在注释中使用未命名的参数,也没有解决问题。但是,如上所述,使用未命名的参数解决了我的问题。