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");
Related
I have a Spring Mvc application, in registration form i have an area for email and name
Before registering i check that all fields are unique in the DB with the following code in service layer (I'm using spring data)
#Override
public Optional<String> isUnuque(final Users user) {
if (this.repository.findByEmail(user.getEmail()) != null) {
return Optional.of("Your email is not unique");
} else if (this.repository.findByName(user.getName()) != null) {
return Optional.of("Your name is not unique");
}
return Optional.empty();
}
Then in controller i check if Optional is present. But with this code i make 2 requests to the DB, i can use native query like this to make only one request:
select * from users where name = 'dd' or email = 'ddd#mail.ru'
But how would i know which parameter is not unique name or email?
Thank in advance
BTW i solved this problem with the following code
#Override
public Optional<String> isUnuque(final Users user) {
final Users dbUser = this.repository.findByEmailOrName(user.getEmail(), user.getName());
if (dbUser != null) {
if (user.getEmail().equals(dbUser.getEmail())) {
return Optional.of("Not unique email");
} else {
return Optional.of("Not unique name");
}
}
return Optional.empty();
}
But if there are any sql query that can do exactly what i want without double checking in service layer please write it below
I'm not a java expert but as a database guy, I would say a better way would be to enforce the UNIQUE constraint on name and email in the table and handle the exception, which maintains the data integrity regardless of the application.
Another option is to get the count of emails and names with the given arguments.
SELECT count(CASE
WHEN name = :p_name
THEN 1
END) AS name_count
,count(CASE
WHEN email = :p_email
THEN 1
END) AS email_count
FROM users;
The COUNT function does not count nulls, so when condition in CASE is false( by default NULL), it adds 0 to the count. So, effectively the query would return name_count and email_count as 0 or 1 depending on the existing value, which you should be able to use in your code.
Union All can do this.
select 'name' from users where name = 'dd'
union all
select 'email' from users where name = 'ddd'#mail.ru
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 have a app that uses MySQL, JPA with EclipseLink.
I'm trying to get from the DB the collection of User flagged as "ACTIVE" and that are not already in a List already loaded in the application.
That is my method:
public List<User> findAllButUsers(List<User> users) {
List<User> list = null;
Query query = em.createQuery("SELECT u FROM User u WHERE u NOT IN :users AND u.status = :status");
query.setParameter("status", "ACTIVE");
query.setParameter("users", users);
list = query.getResultList();
return list;
}
And the Log from server gives me that:
Fine: SELECT iduser, create_time, email, name, password, salt, status FROM user WHERE ((iduser NOT IN (?)) AND (status = ?))
bind => [com.wa.gp.jpa.entities.User[ iduser=2 ], ACTIVE]
From the bind => [com.wa.gp.jpa.entities.User[ iduser=2 ], ACTIVE] shows me that instead of binding the id it passes the value from User.toString method thus resulting in a Collection that includes the users passed. I thought it would work just sending the object to JPA and it would figure out the iduser by itself.
I don't know if it is a expected behavior, looks to me it is. How can I just make that query without having to change the valor from tostring in User? Do I have to instead of giving the List of Users just pass a List of the Ids? If that is the case I just became said.
Thanks
I understand some might simply answer this question with "Why didn't you just Google it"... But I did, and the more I researched this the more confused I got. I'm trying to query my database with Hibernate, the query has a 'where' clause.
Now creating a database entry is easy enough, in the case where I have a 'User' class, I simply do this:
// Gets a new session
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
// Creates a new User object
User user = new User("John", "p#55w0rd*", "john#doe.com");
// Save and commit
session.save(user);
session.getTransaction().commit();
But what do I do when I what to for instance
select * from Users where id = '3';
My Google searches pointed to something called HQL, which makes me wonder why I couldn't of just used straight JDBC then. Also it doesn't seem very object oriented. And then there's something like
session.createCriteria(.......
But I'm not sure how to use this.. Any help? Thanks guys.
When you use Native Query (non HQL ) you need to tell hibernate explicitely to handle it like below :
In below query createSQLQuery is special function to handle native sql's
String sql = "SELECT * FROM EMPLOYEE WHERE id = :employee_id";
SQLQuery query = session.createSQLQuery(sql);
query.addEntity(User.class);
query.setParameter("employee_id", 3);
List<User> results = query.list();
This can be done using criteria as well for that following is good starting point:
Criteria criteria = sess.createCriteria( User.class);
List<User> users= criteria.list();
http://www.developerhelpway.com/framework/hibernate/criteria/index.php
First of all, you need a hibernate.cfg.xml which contains properties for hibernate. This is e.g url, username and password, the driver and dialect. This file is placed in a package called resources.
You have to choose between using Hibernate Annotations example
or using hbm.xml files example
This is how you tell hibernate what your database is like. It wil automatically create queries for you based on how you annotates or defines in e.g user.hbm.xml.
Create a HibernateUtil.java class which holds the session factory.
You can fetch data from the database with
Criteria crit = getSessionFactory().getCurrentSession().createCriteria(User.class);
Example using queries:
List<?> hibTuppleResultList = currentSession.createQuery(
"from Person p, Employment e "
+ "where e.orgno like ? and p.ssn = e.ssn and p"
+ ".bankno = ?")
.setString(0, orgNo).setString(1, bankNo).list();
for (Object aHibTuppleResultList : hibTuppleResultList)
{
Object[] tuple = (Object[]) aHibTuppleResultList;
Person person = (Person) tuple[0];
hibList.add(person);
}
In the end all I really wanted was to know that if you don't want to use HQL you get something called 'Criteria Queries', and that in my case I'd do something like this:
Criteria cr = session.createCriteria(User);
cr.add(Restrictions.eq("id", 3));
List results = cr.list();
Me: "Thanks!"
Me: "No problem :)"
PS - we can really delete this question.
Query q = session.createQuery("from User as u where u.id = :u.id");
q.setString("id", "3");
List result = q.list();
Query with Criteria:
Criteria cr = session.createCriteria(User.class);
List results = cr.list();
Restrictions with Criteria:
Criteria cr = session.createCriteria(User.class);
cr.add(Restrictions.eq("id", 3));
// You can add as many as Restrictions as per your requirement
List results = cr.list();
You could also use it like this
List results = session.createCriteria(User.class).add(Restrictions.eq("id", 3)).list();
Some example for Crieteria Rsetriction query
Criteria cr = session.createCriteria(Employee.class);
// To get records having salary more than 2000
cr.add(Restrictions.gt("salary", 2000));
// To get records having salary less than 2000
cr.add(Restrictions.lt("salary", 2000));
// To get records having fistName starting with zara cr.add(Restrictions.like("firstName", "zara%"));
// Case sensitive form of the above restriction.
cr.add(Restrictions.ilike("firstName", "zara%"));
// To get records having salary in between 1000 and 2000
cr.add(Restrictions.between("salary", 1000, 2000));
// To check if the given property is null
cr.add(Restrictions.isNull("salary"));
// To check if the given property is not null
cr.add(Restrictions.isNotNull("salary"));
// To check if the given property is empty
cr.add(Restrictions.isEmpty("salary"));
// To check if the given property is not empty
cr.add(Restrictions.isNotEmpty("salary"));
You can create AND or OR conditions using LogicalExpression restrictions as follows:
Criteria cr = session.createCriteria(Employee.class);
Criterion salary = Restrictions.gt("salary", 2000);
Criterion name = Restrictions.ilike("firstNname","zara%");
// To get records matching with OR condistions
LogicalExpression orExp = Restrictions.or(salary, name);
cr.add( orExp );
// To get records matching with AND condistions
LogicalExpression andExp = Restrictions.and(salary, name);
cr.add( andExp );
List results = cr.list();
I think this will help you
I'm doing my own DAO classes using plain JDBC as an exercice.
Now, does something like an SQL LIKE fit into the DAO pattern ?
What I'd like to do is support a search feature which matches a field against a string. Is there another approach that is more suitable to OOP ?
A function with a good comment can fit your need :)
class MyDAO {
/* Search user which name contains searchName */
public List<User> searchUserByName(String searchName) {
String sql = "select * from USERS where USERNAME like '%" + searchName + "%'";
List<User> users = new ArrayList<User>();
// Execute sql,
// open ResultSet,
// iterate it and for every ResultRow's row convert to object User
// Add converted object User to users
// Free resource
return users;
}
}
This is just an idea, you need transaction management, connection supplier and so on