I made a REST service project where i was performing CRUD operations via DriverManager.getConnection(url,user,pass).
Now my asignment changed to defining the connection in Jboss 7.1.1 and that is working (Testing the datasource in the Jboss admin console returns positive and the sqljdbc driver also appears active in the Activity Monitor of MS SQL Server Management Studio).
I am suposed to use the EntityManager to run the native querys i used with the old project without generating entities or writing queries using entities(Thats for the next asignment).
I wrote a small test code from what i found in my research, the following:
public class Test {
#PersistenceContext(unitName="InternshipIS") protected EntityManager entityManager;
public void getQuerys(){
String sqlQuery = "SELECT * from InternshipIS.dbo.Employee";
Query q = entityManager.createNativeQuery(sqlQuery);
System.out.println(q.getResultList().get(2));
}
When it reaches the following line, it throws a NullPointerException.
Query q = entityManager.createNativeQuery(sqlQuery);
Please let me know where i'm screwing up and if the full stacktrace / persistence.xml / standalone.xml or anything else is needed in order to add them to my post.
PS: This is not a maven project. It was a Dynamic Web Project that i converted to JPA when this asignment started.
I fixed the problem by making the following adjustments:
public class Test {
public void getQuerys(){
EntityManagerFactory emFactory = Persistence.createEntityManagerFactory("InternshipIS");
EntityManager em = emFactory.createEntityManager();
String sqlQuery = "SELECT * FROM Employee";
Query q = em.createNativeQuery(sqlQuery);
}
}
String sqlQuery = "SELECT * from InternshipIS.dbo.Employee";
In this query, Select * from InternshipIS is understandable for sql.
But I think you are concatenating database name with table in query. Which is not working and query returning null value.
Related
I am trying to run some native SQL queries in my Spring application. I donĀ“t have an entity or JpaRepository class. I know it's strange, but this is a microservice just to collect two count queries and send it to Kafka.
Well trust me, all I need is these two integers from the queries. I run these code and always returns 0. I can see in the logs that Hikari is connecting to the database, so I don't know what to do. Searched a lot, but all answers involved the #Query solution, which does not work for me.
#Repository
#AllArgsConstructor
public class ReportRepository {
private final EntityManager em;
public int numberOfAccounts() {
String sql = "SELECT count(*) FROM account";
Query query = em.createNativeQuery(sql);
System.out.println(query.getFirstResult());
return query.getFirstResult();
}
public int numberOfSubscriptions() {
String sql = "SELECT count(*) FROM subscriptions";
Query query = em.createNativeQuery(sql);
System.out.println(query.getFirstResult());
return query.getFirstResult();
}
}
If you have EntityManager, and from what you are saying it can connect to DB, try this way:
public int numberOfSubscriptions() {
// >> "subscriptions" has to be the exact name of your table
// if does not work, consider trying SUBSCRIPTIONS or Subscriptions
String sql = "SELECT count(*) FROM subscriptions";
Query query = em.createNativeQuery(sql);
// getSingleResult() instead :)
return ((Number) query.getSingleResult()).intValue();
}
There is this (a bit old) JavaDoc for Query.getFirstResult() :
The position of the first result the query object was set to retrieve. Returns 0 if setFirstResult was not applied to the query object
So, I'd say that is not the right method for your case.
Happy Hacking :)
You should be using JDBC instead of an Entity Manager. Under the JPA uses JDBC but it requires defined entites to work. JDBC allows you to manage the connection and run the raw SQL queries.
Here's a link for how to do it in Spring:
https://spring.io/guides/gs/relational-data-access/#_store_and_retrieve_data
I am currently upgrading our application and we are migrating from Hibernate 3.x and Spring/Spring Security 3.x to Hibernate 5.x and Spring/Spring Security 5.x respectively. We had some methods that executed native sql update queries (example 1), but after upgrading to 5.x the methods started throwing TransactionRequiredException: Executing an update/delete query exceptions. Well I tried adding the #Transactional annotation on the methods but it doesn't seem to help. I will share the old method and the upgraded method (example 2).
I don't understand how it is not working on the new version, did Hibernate change the way they treat native sql queries? Thanks for the responses.
Example 1
public void myTestMethod() {
String sql = "Update myTable set State = 1";
Session session = getSessionFactory().openSession();
Query query = session.createSQLQuery(sql);
query.executeUpdate();
session.close();
}
Example 2
public void myTestMethod() {
String sql = "Update myTable set State = 1";
Session session = sessionFactory.openSession();
Query query = session.createNativeQuery(sql);
query.executeUpdate();
session.close();
}
What am I doing wrong here? How can I execute this update without changing much in the methods (we have thousands of methods implemented). The sessionFactory in the example 2 is injected with #Inject annotation.
Try to use #Transactional over your methods and use getCurrentSession() instead of the openSession()
And your code has session.close() statement which doesn't make sense any more, since the connection was already closed and managed by the spring. Try removing the session.close() statement and try again
I have a spring application that should connect to an existing database and just query an entity for existence based on some attributes.
I don't want to create a #Entity class for this. But I still want to use the spring managed EntityManager etc.
When using Spring, what is the best approach to just query a select for that entity? Using em.createNamedQuery(QUERY); with String QUERY = "SELECT count(*) from my_table where username =: username AND email := email)";?
Answers from #predrag-maric and #pL4Gu33 are both correct but if you use JPA in your project (for example, Hibernate) you might consider using #NamedNativeQuery annotation as well.
More about named native queries.
simple example of native query
#PersistenceContext
EntityManager em;
public String test(Integer id)
{
Query query = em.createNativeQuery("SELECT name FROM Accounts where id=?");
query.setParameter(1,id);
return query.getSingleResult();
}
You can use this method from entitymanager. http://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#createNativeQuery%28java.lang.String%29
Use em.createNativeQuery(QUERY). Also, you'll have to use positional parameters (?1) instead of named parameters (:email), because only positional parameters are supported by JPA in native queries.
I have a postgres function written currently called do_function(), It does not return anything. I am creating a button on my web page that by pressing it will execute this function on the data base.
Is the following a good way to do this? I get an error: No Dialect mapping for JDBC type: 1111
Currently I have in the RS:
#GET
#Path("/doFunction")
public void doFunction(#Context HttpServletRequest request)
{
getDao().doFunction;
}
In the DAO:
#Transactional
public void doFunction()
{
Session session = (Session) entityManager.getDelegate();
SQLQuery query = session.createSQLQuery("SELECT * FROM do_function()");
query.uniqueResult();
}
If when you say "does not return anything" you mean "returns void", many Java ORMs don't understand the void pseudo-type.
You might be able to avoid confusing them by instead invoking:
SELECT do_function();
but otherwise, use a dummy result like:
SELECT 1 FROM do_function();
to avoid hurting the ORM's poor little brain.
In Mysql,
SELECT id FROM table ORDER BY RANDOM() LIMIT 5
this sql can select 5 random rows. How to do this via JPA Query (Hibernate as provider, Mysql database)?
Thanks.
Only the functions defined in the specification are guaranteed to be supported by all JPA providers and RAND or RANDOM aren't. So I don't think that you can do it in JPQL.
However, it would be possible in HQL (the order by clause in HQL is passed through to the database, so you can use any function):
String query = "SELECT o.id FROM Order o ORDER BY random()";
Query q = em.createQuery(query);
q.setMaxResults(5);
But, I repeat:
This may not work with another database.
This may not work with another JPA provider.
Try calculating the random beforehand and construct your JPQL/HQL/native query with the pre-calculated random value.
I just Achieved this by a simple way, This may not seem lot of cute but it will do the purpose. this solution is for Java 8 or above only, I m using spring boot.
First I have the following service call that will provide an EntityManager to my default Repository interface method, The autowiring is a singleton so I believe that this stays performance freindly.
#PersistenceContext
private EntityManager entityManager;
#Override
public UserResp getRandomUser() {
long orderByRandom = (long) ((java.lang.Math.random()*100 % 10 )+1);
return userMapper.entityToModel(userRepository.pickRandomUser(orderByRandom,entityManager));
}
Then my repository looks like
#Transactional
default User pickRandomUser(Long rand, EntityManager manager) {
return manager.createQuery("SELECT u FROM User u ORDER BY "+rand,User.class).setMaxResults(1).getSingleResult();
}