Java method to log in from user from hibernate - java

I learning Java, SQL, Hibernate and I must make a method to log in as user from MySQL DB. I'm trying write the code but I can't compare String from scanner and from DB. I don't have Spring for now.
import com.sda.util.HibernateUtil;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.util.Scanner;
public class UserLogging {
EntityManager em = HibernateUtil.getSessionFactory().createEntityManager();
Scanner scanner = new Scanner(System.in);
public void logging() {
System.out.println("Enter email:");
String userInputEmail = scanner.nextLine();
em.getTransaction().begin();
Query query = em.createNativeQuery("select from user u where u.email = :?", User.class);
query.setParameter("?", userInputEmail);
if (userInputEmail.equals(query.toString())) {
System.out.println("You are logged in.");
} else
System.out.println("Login failed.");
em.getTransaction().commit();
}
}

The best thing you can do to learn a new language/technology is to just try out stuff and to figure it out yourself!
E.g. try using a debugger - If you don't know what that is or how to use it, just watch a tutorial online :) This helps a ton on finding out, what exactly is wrong with your code -> Thus helping you narrowing down your problem even more, so you can e.g. google more specific questions.
But to answer your question, and maybe a few more:
Transactions
Generally, you don't have to create a transaction for each query; As long as it's just a SELECT. (You're not changing anything in the DB, which means you're not altering any information; Nothing happens to your data, even if your program were to crash).
Speaking of transactions: transaction.commit() does not execute your query. It just commits the transaction; Meaning, it's not rolled back.
The query itself
As stated previously, transaction.commit() doesn't execute any queries.
And spoiler alert: query.toString() doesn't do it either.
You should use query.getResultList() and then you're able to iterate over it by e.g. using a while loop.
Cleaner syntax
You can also link multiple things together like this:
em.createNativeQuery("...", User.class)
.setParameter(...)
.getResultList();

Related

Log how many items have been impacted in a Spring/Hibernate transaction

I have this method that is called from another service:
#Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public void execute(String sql) {
Query query = entityManager.createNativeQuery(sql);
query.executeUpdate();
}
Basically the client loads multiple sql files and run each sql file in a new transaction, in order to not impact other files execution.
For example this is an example of an sql file, that is cleaning up some data:
begin;
delete from table t where t.created_at < current_date - interval '2 month';
commit;
What I'm trying to do is to log, the outcome of each transaction. For example here, I want to display how many records were deleted. How can I do that from Spring ? I know that you can log something more specific with:
logging.level.org.springframework.transaction=TRACE
, but still I cannot see any outcome. This reveals information about sql that will run and when transaction started/ended.
Second solution was to check the result of:
int count = query.executeUpdate();
, but count is 0, even though the sql code got executed and deletes hundreds of rows.
Thanks upfront for the suggestions !
The problem is as #XtremeBaumer correctly pointed out your script. If you just run executeUpdate with a delete statement it will return the number of affected rows.
But that is not what you are doing. You are executing a code block delimited by begin and end. There might be a way for such a code block to return a value, but that would need to be coded into the code block and is probably highly database specific.

Spring Application takes too much time

I had written a SpringMVC code to export PostgreSQL databases to ndjson files, The code works. However, One of the tables take like 10seconds ( Careplan ) for 100 records !
the following is the code for DAO class
public List<DafCarePlanParticipant> getCarePlanparticipantByCareTeam(int id)
{
Criteria criteria = getSession().createCriteria(DafCarePlanParticipant.class, "dp").add(Restrictions.eq("careteam", id));
List<DafCarePlanParticipant> dafCareTeam = criteria.list();
return dafCareTeam;
}
I've running into deadends without any success of optimizing this code. Can i get some help, please!
Thank you !
I think the problem maybe due to getSession(). Since getSession() might create a new Session, it consumes time to create a new session every time and exhaust your datasource.
Try to use getCurrentSession() instead to see if any improvement.

Hibernate's SQLQuery executeUpdate function starts, but does not fully execute

Working on a Spring application that uses Hibernate, and in my DAO layer we are running an UPDATE statement to update some values in an Oracle database.
To make sure I'm not crazy, I ran the statement in SQL Developer to make sure it works properly. Here is part of my DAO code:
public void updateObjectInMyTable(SomeClassA objectOfSomeClassA) {
Session session = getCurrentSession();
String sql = "UPDATE SCHEMA_NAME.TABLE_XYZ SET FIRST_NAME=:firstName, LAST_NAME=:lastName, ADDRESS=:address, CITY=:city, ZIPCODE=:zipcode WHERE ID_NUMBER = :idNumber";
SQLQuery query = session.createSQLQuery(sql);
query.setParameter("firstName", objectOfSomeClassA.getFirstName());
query.setParameter("lastName", objectOfSomeClassA.getLastName());
query.setParameter("address", objectOfSomeClassA.getAddress());
query.setParameter("city", objectOfSomeClassA.getCity());
query.setParameter("zipcode", objectOfSomeClassA.getZipcode());
query.setParameter("idNumber", objectOfSomeClassA.getIdNumber());
query.executeUpdate();
}
(Excuse the poor variables names used for substitutions of the real ones.) I did debug on the server and I do not see any errors with query.executeUpdate() It gets to that line, and doesn't pass on to the next statement I have in my service layer.
Anything I'm doing wrong?
Where's your transaction ?!
Use :
session.beginTransaction().commit();
add this in the end line of your code.
I hope this helps you.

How to enter SQL instruction in controller with play 2 and java

I'm developing a web application with Play 2.1.0 and programming it with Java and I need to have access to data already saved in a DB to modify them.
I tried to create a new instance without the new operator and reference it to my object saved in the database, but even if there is no pointer error, it won't change values of attributes. I couldn't figure out why, so I've decided to enter SQL queries directly.
Same thing, it does not seems to have any mistake, but it won't change anything... I think this comes from a bad link to the database :
Here is my code in application.java :
public static Result modifyQuestionnaire(Long id) throws SQLException {
Statement stmt = null;
Connection con = DB.getConnection();
try {
stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
String query = "SELECT * FROM WOQ.questionnaire WHERE id=id";
ResultSet uprs = stmt.executeQuery(query);
uprs.updateString("name", "baba");
uprs.updateRow();
} catch(Exception e) {
e.printStackTrace();
} finally {
if (stmt!=null) {
stmt.close();
}
}
return redirect(routes.Application.questionnaire(id));
}
And I also try to enter an UPDATE query directly, still the same..
I've looked everywhere and did not find any solution (except Anorm but it seems to work with Scala language)
Btw, if anyone knows a solution with a second instance that refers to the same object (it seems possible but as I say, there is no error but no actions neither), it's fine for me.
Huh, you showed as that you are trying to create totally new connection, so I supposed, that you don't want to use Ebean, but in case when you are already use it, you can just use its methods for the task:
(copied) There are some options in Ebean's API, so you should check it and choose one:
Update<T> - check in the sample for #NamedUpdates annotation
Ebean.createUpdate(beanType, updStatement)
SqlUpdate - you can just perform raw SQL update, without need for giving the entity type

Hibernate Batch Processing Using Native SQL

I have an application using hibernate. One of its modules calls a native SQL (StoredProc) in batch process. Roughly what it does is that every time it writes a file it updates a field in the database. Right now I am not sure how many files would need to be written as it is dependent on the number of transactions per day so it could be zero to a million.
If I use this code snippet in while loop will I have any problems?
#Transactional
public void test()
{
//The for loop represents a list of records that needs to be processed.
for (int i = 0; i < 1000000; i++ )
{
//Process the records and write the information into a file.
...
//Update a field(s) in the database using a stored procedure based on the processed information.
updateField(String.valueOf(i));
}
}
#Transactional(propagation=propagation.MANDATORY)
public void updateField(String value)
{
Session session = getSession();
SQLQuery sqlQuery = session.createSQLQuery("exec spUpdate :value");
sqlQuery.setParameter("value", value);
sqlQuery.executeUpdate();
}
Will I need any other configurations for my data source and transaction manager?
Will I need to set hibernate.jdbc.batch_size and hibernate.cache.use_second_level_cache?
Will I need to use session flush and clear for this? The samples in the hibernate tutorial is using POJO's and not native sql so I am not sure if it is also applicable.
Please note another part of the application is already using hibernate so as much as possible I would like to stick to using hibernate.
Thank you for your time and I am hoping for your quick response. If it is also possible could code snippet would really be useful for me.
Application Work Flow
1) Query Database for the transaction information. (Transaction date, Type of account, currency, etc..)
2) For each account process transaction information. (Discounts, Current Balance, etc..)
3) Write the transaction information and processed information to a file.
4) Update a database field based on the process information
5) Go back to step 2 while their are still accounts. (Assuming that no exception are thrown)
The code snippet will open and close the session for each iteration, which definitely not a good practice.
Is it possible, you have a job which checks how many new files added in the folder?
The job should run say every 15/25 minutes, checking how much files are changed/added in last 15/25 minutes and updates the database in batch.
Something like that will lower down the number of open/close session connections. It should be much faster than this.

Categories