my question is to change password for user that is logged in the system. It prints out new password changed successfully but when i check it, the password remains the same and has not been changed. Is it because i use set.Password? Is there other ways? This code tries to retrieve Employee using username.
UPDATED : This question has been resolved by Alex's brilliant answer along with the other suggestions! Thank you all.
This is the method to invoke the remote controller
private void doChangePassword() throws UserNameNotFoundException, EmployeeNotFoundException {
Scanner scanner = new Scanner(System.in);
System.out.println("*** Administration Panel :: Change Password ***\n");
System.out.print("Enter username> ");
String username = scanner.nextLine().trim();
System.out.print("Enter current password> ");
String currentPassword = scanner.nextLine().trim();
System.out.print("Enter new password> ");
String newPassword = scanner.nextLine().trim();
System.out.print("Enter new password again> ");
String reenterNewPassword = scanner.nextLine().trim();
currentEmployee = employeeControllerRemote.retrievePasswordByUsername(username);
if (currentPassword.equals(currentEmployee.getPassword())) {
if (newPassword.equals(reenterNewPassword)) {
currentEmployee.setPassword(newPassword);
//Updated here
employeeControllerRemote.updateNewPassword(currentEmployee);
System.out.println("New Password changed successfully!\n");
} else {
System.out.println("New Password mismatched!\n");
}
}
else {
System.out.println("Wrong password, please try again later");
}
}
In another program, stateless session bean called employeeController. This method is implemented in employeeControllerRemote and local as well.
#Override
public Employee retrievePasswordByUsername(String username) throws UserNameNotFoundException {
Query query = em.createQuery("SELECT e FROM Employee e WHERE e.username = :inUsername", Employee.class);
query.setParameter("inUsername", username);
return (Employee) query.getSingleResult();
//Changed it according to suggestions
}
This is the new method that i created. I tried to use commit but it didn't work. I also tried to use persist and flush. But it says that it is a duplicate and there were illegal arguement errors. The flush did not work as well and the error code mentioned that there was nothing to flush.
I created this new method did not put it under retrievePasswordByUsername method because i think that it should not be there since it just retrieves it? So i created a new method below. It still does not work though.
#Override
public void updateNewPassword(Employee employee) {
//em.getTransaction().begin();
em.flush();
//em.getTransaction().commit();
}
Thank you all for your time! :)
You should not do the password updating in your doChangePassword() method, as it is in client side. It cannot update anything to database directly. It needs to do it via your stateless session bean.
So you should modify your method in stateless session bean to do the update job.
#Override
public void updatePasswordByUsername(String username, String password) throws UserNameNotFoundException
{
Query query = em.createQuery("SELECT e FROM Employee e WHERE e.username = :inUsername");
query.setParameter("inUsername", username);
//query.getSingleResult();
Employee employee = (Employee) query.getSingleResult();
employee.setPassword(password);
em.persist(employee);
}
Then you call this method in your client side through stateless session bean.
You may need to check the old password again in your stateless session bean in order to avoid attacks that bypass your client-side checking.
You need to persist the changed Entity/Data. entityManager.persist(employee); after you set the new PW.
Here are some other hints:
Casts shouldn´t be done. You can modify to this.
Query query = em.createQuery("SELECT e FROM Employee e WHERE e.username = :inUsername", Employee.class);
query.setParameter("inUsername", username);
return query.getSingleResult(); // now EMPLOYEE
Your workflow sould be:
Enter userName
Check if user exists (byName)
Input currentPassword, newPassword, newPasswordConfirm
Change the values
Persist your User/Employee so the change will be in DB, too. Without saving it in DB you just changed the local used Object-Instance.
you should use one of these "save, persist, update, merge, saveOrUpdate"
Try using the EntityManager.merge method - this is very similar.
employee.setPassword(newPassword);
em.merge(employee);
Related
I have a problem. I need to display the value from the line and transfer it to the database. I'm using a timelif, and so, I get the error "Order is not mapped", and points to line 31, in fact, to my HQL query. Structure: I enter a word in the field, the timelif transfers it to the post request of the spring, and the same transfers it to the function. It is necessary to write the request somehow correctly so that the text is entered into the database. My code:
public String createOrder (#ModelAttribute("order") Orderdao orderdao, String text){
orderdao.createOrder(text);
return "redirect:/";
}
Function:
public void createOrder(String text) {
Transaction tx = null;
try (Session session = BogPomogi.getSessionFactory().openSession()) {
session.beginTransaction();
System.out.println(text);
Query create = session.createQuery("insert into Order(text)" + "select text from text");
int result = create.executeUpdate();
session.getTransaction().commit();
session.close();
}
Help me please
i solved it with: Query query = session.createSQLQuery("INSERT INTO orders (text, status, customer) VALUES (:text, :status, :customer)");
(sql request)
I have a table called ad_session which logs user sessions. I am using Java to get a list of all successful sessions from that table. I then loop through that list to get the user for each session (which is a foreign key to the ad_user table). I then get the client that belongs to that user, and I add the client to a list. However, one of the users no longer exists, so my code stops running and it gives throws the following exception:
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [ADUser#76A5C22E6D2446A399AE9AD7C1DED0C7]
This is my original code:
List<Session> sessions = getAllSuccessfulSessionsInTable();
List<Client> clientsForThatDay = new ArrayList<>();
try {
for (Session session : sessions) {
//code fails when trying to get the non-existent user:
User user = session.getCreatedBy();
Client userClient = user.getClient();
clientsForThatDay.add(userClient);
}
} catch (Exception e) {
log.error("Error getting client from user: ", e);
}
I assumed that when getting a non-existent record, it would return null, so this is what I tried:
List<Session> sessions = getAllSuccessfulSessionsInTable();
List<Client> clientsForThatDay = new ArrayList<>();
//Create new user object to stand in place of the non-existent user
User deletedUser = new User();
deletedUser.setName("Deleted User");
//Create new client object to stand in place of the non-existent client
Client deletedUserClient = new Client();
deletedUserClient.setName("Unknown Client");
try {
for (Session session : sessions) {
//check is User is null, if it is, use the deletedUser object, otherwise, use the existing user
User user = session.getCreatedBy() == null ? deletedUser : session.getCreatedBy();
Client userClient = user.getName().equals("Deleted User") ? deletedUserClient : user.getClient();
clientsForThatDay.add(userClient);
}
} catch (Exception e) {
log.error("Error getting client from user: ", e);
}
However, it is not returning null, it's just throwing the exception and then stopping.
How can I get it to return null here so I can deal with the missing record without my code stopping?
Thanks in advance for any suggestions.
It seems that your database is missing a foreign key constraint.
This means that the table mapping User has a reference to a row in the table for Client that no longer exist.
This can only happen if a client has been deleted without updating the user table. The solution would be to add a foreign key constraint between the tables.
Keep in mind that if the data in your tables are not correct, when Hibernate loads the entity User, it will also believe there's a client. This means that User#getClient won't be null, and every place in the code where you have a check like user.getClient() == null is going to fail. A try-catch approach won't help you with this (unless you set the association to null in case of error, I guess).
The solutions I can think of:
Add the foreign key constraint (imho, the best solution)
Don't map the association, map client_id as an attribute and load the client using a second query or find (I would only do this if you cannot update the database)
class User {
#Column(name = "client_id")
Long clientId;
}
User user = ...
Client client = session.find(Client.class, user.getClientId());
You can load the client via session.find(Client.class, user.getClient().getId()) and set the association with the result:
User user = //...
Client client = session.find(Client.class, user.getClient().getId());
user.setClient(client);
Don't map the association at all in User, and run a native SQL query to load the client:
User user = ...
String sql = "select * from Client c join User u on c.id = u.client_id where u.id = :uid";
Client client = session.createNativeQuery(sql, Client.class)
.setParameter("uid", user.getId())
.getSingleResultOrNull();
You can pick what works best for you, but keep in mind that mapping an association without the foreign key constraint, will cause all sort of consistency issues.
I've decided to put option 3 only because, sometimes, people have some impossible situations at work, but I wouldn't recommend it.
Hello i have a two questions. What is best way to check/find is exist some value. For example i have in my db
and i wanna check in my login swing app someone login and pass.
How can i build a query?
i was try
EntityManagerFactory entityManagerFactory=Persistence.createEntityManagerFactory("library");
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
Query query = entityManager.createQuery("from users");
//query.setParameter(1,forLogin.getText());
//query.setParameter(2,forPassword.getText());
System.out.println(query.getFirstResult());
But always is say 0. Even when i add parameter with good value is still 0. I know is function .find() but it can take only(?) id parametr or i dont know how can i pick it using other column. And second question. I need in every class create entitymanager+factory when i wanna use db or is some other way? Because when i wanna use it when i open in other class is saying "session closed".
Try this. You have to replace the class of the entity and the field of the user name and password
EntityManagerFactory emf = Persistence.createEntityManagerFactory("library");
EntityManager em = entityManagerFactory.createEntityManager();
// Query with where clausel
// I 'lower' the user name and use a TypedQuery
// the password should be case sensentive
TypedQuery<User> query = entityManager.createQuery("from users u where lower(u.username) = :name and u.password = :password", User.class);
query.setParameter("name", "foo");
query.setParameter("password", "pwd");
try {
User user = query.getSingleResult();
System.out.println("User found");
} catch( javax.persistence.NoResultException e ){
System.out.println("No user found");
}
I have recently asked quite similar question here, but answer does not solve my new problem.
I have two tables: User and Book, they are in ManyToOne relation. The Book table has attribute called user_id that connects both tables. Using Eclipse I generated entity classes, and "user_id" was created not as Integer like in database, but:
#JoinColumn(name="user_id")
private User user;
So now when i try to create new "Book" like this:
public String saveData() {
if(!validate()){
...
if (book != null) {
System.out.println(getUser());
setName(book.getName());
System.out.println("Post3");
setSurname(book.getSurname());
setAdress(book.getAdress());
setSize(book.getSize());
setContact(book.getContact());
setPrice(book.getPrice());
setOthers(book.getOthers());
setIsReady(book.getIsReady());
setRooms(book.getRooms());
setUser(book.getUser());
System.out.println(user);
}
private boolean validate() {
FacesContext ctx = FacesContext.getCurrentInstance();
boolean result = false;
System.out.println("validate");
if (ctx.getMessageList().isEmpty()) {
book.setName(name.trim());
book.setSurname(surname.trim());
book.setAdress(adress.trim());
book.setSize(size.trim());
book.setContact(contact.trim());
book.setPrice(price);
book.setOthers(others.trim());
book.setIsReady(isReady.trim());
book.setRooms(rooms);
book.setUser(user);
result = true;
}
return result;
}
...
bookDAO.create(book);
I'm getting
Column 'user_id' cannot be null
I am not sending 'user_id' in form but I have it stored in session BUT as integer.
So now when I am trying to force that int into the setUser I get an error that I can use only User objects there.
So my question is, are there any ways to convert Integer(which my id_user is) into the User?
You need to get User object from your database using the user_id in your session.
If you are using JPA entitymanager
User user = entityManager.find(User.class, user_id);
book.setUser(user);
You must select User by user_id from your database, or just
User user = new User();
user.setUserId(id_user);
book.setUser(user);
I am using
List<USERS> user =
getHibernateTemplate().find("select uid, username,email from USERS");
to get three columns values from the users TABLE. But I can access no individual column value using the "user" object because the "user" type is an object type and I can't cast it to the USERS.
Is there any ways to use the "user" object and access individual columns value?
Why are you just querying selected columns - just get the whole row(s). Let me know if that helps.
If you are fetching only few columns, the hibernate template will return a list of object arrays.
Your example should look like this,
List<Object[]> userDetails =
getHibernateTemplate().find("select uid, username,email from USERS");
And you should know the first element is a integer and second, third are string and do cast on your own. This is very error prone ofcourse.
Thanks Nilesh and Sean for your suggestions. I always deal with the objects instead of individual columns. But this specific app works with other tables from another app which is not written in Java (That is why I am using USERS table not "User", because it is already created by another app) and is not using hibernate. I created a USERS class that implements UserDetails and has much less columns than the original app USERS table. When I get the whole object I get a formatting error that is why I tried using selected columns instead of the object.Anyhow I wrote this code and was able to get the individual columns:
List user=
getHibernateTemplate().find("select uid, username,email from USERS where uid<>0 AND obj_type=1");
List<USERS> l = new ArrayList<USERS>();
for (int i = 0; i < user.size(); i++) {
USERS du = new USERS();
Object[] obj = (Object[]) user.get(i);
Integer uid = (Integer) obj[0];
du.setUid(uid);
String username = (String) obj[1];
du.setUsername(username);
String email = (String) obj[2];
du.setEmail(email);
l.add(du);
}
My last question: isn't it more expensive to get the whole columns(the object) than getting the individuals ones?
Keep in mind it that...
getHibernateTemplate.find() method returns List of based on passed object.
Then after this you have to take List of Users then you have to separate all resulting object and after specified a object you can access attribute of it.
Its very easy..
If you have any query then tell me
I will try my best.
#Override
public Object findByNo(Object id) throws Exception {
List list = getHibernateTemplate().find(
"select book from Book book " +
"where book.id=?",id);
if (list.size() != 0) {
return list.get(0);
} else {
return new Book();
}
}
I'm guessing your db table is called USERS and the entity class is called User. If that is the case, then you should do something like this:
List<User> users = getHibernateTemplate().find("from User");
for(User user: users){
// you probably don't need the id, so I'll skip that
String email = user.getEmail();
String userName = user.getUserName();
// now do something with username and email address
}
If you use an ORM framework, deal with objects, not with Database Columns!
And about naming:
Java naming conventions suggest that a class name is in TitleCase (or more precisely UpperCamelCase), not UPPERCASE. Also, a class that represents a single user should be called User, not Users.
you can try something like this:
for (TemplateAttributes templateAttributes1 : templateAttributes) {
templateAttributes1.setTemplates(templates);
templateAttributes1.setCreateDate(new Date());
templateAttributes1.setCreateUser(ApplicationConstants.userName);
templateAttributes1.setLastModified(new Timestamp(new Date().getTime()));
templateAttributesNew.add(templateAttributes1);
}
templates.setTemplateAttributes(templateAttributesNew);
templates.setUpdateDate(new Date());
templates.setUpdateUser(ApplicationConstants.userName);
templates.setLastModified(new Timestamp(new Date().getTime()));
getHibernateTemplate().bulkUpdate("delete from TemplateAttributes where templateAttributePK.templates.id="+templates.getId());
getHibernateTemplate().update(templates);
Try this
List<USERS> user =(List<USERS>)(List<?>)
getHibernateTemplate().find("select uid, username,email from USERS");