问题
I'm fairly new to JPA (and JPQL by extension). Hopefully, someone will be able to enlighten me with this problem.
The query I'm trying to execute ...
String query = "select u from user u where u.email = '" + userEmail + "' and u.password = sha1('"+ userPassword + "')";
List resultList = emf.createEntityManager().createQuery(query).getResultList();
And I'm getting the follwowing exception ...
Caused by: Exception [EclipseLink-8025] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.JPQLException
Exception Description: Syntax error parsing the query [select u from Utilisateur u where u.email = 'myuser' and u.mot_Passe = sha1('mypassword')], line 1, column 73: unexpected token [(].
Internal Exception: NoViableAltException(83@[()* loopback of 383:9: (d= DOT right= attribute )*])
at org.eclipse.persistence.exceptions.JPQLException.unexpectedToken(JPQLException.java:372)
...
Obviously, I'm missing something here, should I escape the character somehow? specify it in another way? I'll appreciate very much any help on this.
回答1:
I think that JPA doesn't have a sha1 function. So you have two options:
You can implementa a sha1 function on you Java code and use them before load the parameters in the query.
String query = "select u from user u where u.email = :userEmail" + " and u.password = :userPassword"; Query jpqlQuery = em.createQuery(query) .setParameter("userEmail", userEmail) .setParameter("userPassword",sha1(userPassword));
If your database has the sha1 function you can write a native query. Check this link: http://www.oracle.com/technetwork/articles/vasiliev-jpql-087123.html
List<Customer> customers = (List<Customer>)em.createNativeQuery ("SELECT * FROM customers", jpqlexample.entities.Customer.class) .getResultList(); Iterator i = customers.iterator(); Customer cust; while (i.hasNext()) { cust = (Customer) i.next(); //do something }
回答2:
Set the parameters through the Query interface instead of adding them literally to the JPQL String. That way you are also protecting yourself from SQL injection:
String query =
"select u from user u where u.email = :userEmail"
+ " and u.password = sha1(:userPassword)";
Query jpqlQuery = em.createQuery(query)
.setParameter("userEmail", userEmail)
.setParameter("userPassword",userPassword)
回答3:
In EclipseLink you can use the FUNC query word to use a database specific function.
"select u from user u where u.email = :email and u.password = FUNC('sha1', :password)"
See, http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/Support_for_Native_Database_Functions
来源:https://stackoverflow.com/questions/7868939/jpa-how-to-persist-column-with-sha1-encryption