LazyInitializationException in Hibernate and Jersey - java

Hi I am doing a project using Hibernate and Jersey.
In the service layer I am getting a 'LazyInitializationException'. I searched a lot about it.
I saw a solution for creating custom AccessorType. But still I am getting the exception.
Can anyone help me??
I am including more details about it.
Bean: User
#XmlRootElement
#XmlAccessorType(XmlAccessType.PROPERTY)
#XmlAccessorFactory(XmlAccessorFactoryImpl.class)
public class User {
private String userName;
private String password;
private String email;
private String fname;
private String lname;
private Set<MachineTemplate> machineTemplates;
private String photoUrl;
public User() {
machineTemplates = new HashSet<>();
}
public User(String userName) {
this.userName = userName;
}
public User(String userName, String password, String email, String fname,
String lname) {
this.userName = userName;
this.password = password;
this.email = email;
this.fname = fname;
this.lname = lname;
this.machineTemplates = new HashSet<>();
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getFname() {
return fname;
}
public void setFname(String fname) {
this.fname = fname;
}
public String getLname() {
return lname;
}
public void setLname(String lname) {
this.lname = lname;
}
public Set<MachineTemplate> getMachineTemplates() {
return machineTemplates;
}
public void setMachineTemplates(Set<MachineTemplate> machineTemplates) {
this.machineTemplates = machineTemplates;
}
public String getPhotoUrl() {
return photoUrl;
}
public void setPhotoUrl(String photoUrl) {
this.photoUrl = photoUrl;
}
}
DAO Layer method
public User get(String uName) {
Session session = getSessionFactory().openSession();
User u = (User) session.get(User.class, uName);
session.close();
}
Service Layer method
#GET
#Path("/{userName}")
#Produces(MediaType.APPLICATION_JSON)
public User getUserInfo(#PathParam("userName") String userName) {
return userHelper.getUser(userName);
}

The exception says you are trying to load an lazy collection which of out of session. Meaning you need to initialize the collection object before you use. The initialization should happen either in entity setter method or in DAO class. Initializing in setter method of an entity is not recommended usually since it couples your entity with hibernate framework. So best place is DAO layer. But here I have mentioned just for your reference.
Try this
public void setMachineTemplates(Set<MachineTemplate> machineTemplates) {
Hibernate.initialize(machineTemplates);
this.machineTemplates = machineTemplates;
}
Hope this is helpful!

You get the LazyInitializationException when trying to access a lazy fetched atttribute on an entity detached from the persistence context.
It usually means that your hibernate session ( / JPA entityManager) have been already closed when you access the lazy attribute.
see Struggling to understand EntityManager proper use

Actually I dont want to load the machineTemplates data. So I did like
public Set<MachineTemplate> getMachineTemplates() {
if(Hibernate.isInitialized(machineTemplates))
return machineTemplates;
return null;
}

Related

How does java bean validation work in practical

I was wondering have the java bean validation would work in practical, lets say we have a Maven mvc project, with a login form for a user. So we have a jsp/jsf page with the html forms, a Datamapper/DAO for the JDBC connection and a java User bean, which could look like this:
public class Student {
#NotNull(message ="username can't be null)
private String uName;
#NotNull(message ="lastname can't be null)
private String lname;
#Email (regex string="")
private String email;
private int age;
public Student(String uName, String lname, String email, int age) {
this.uName = uName;
this.lname = lname;
this.email = email;
this.age = age;
}
public String getuName() {
return uName;
}
public void setuName(String uName) {
this.uName = uName;
}
public String getLname() {
return lname;
}
public void setLname(String lname) {
this.lname = lname;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
what would happen if a user typped in some not valid information in the view part of the application? What it go all the way down to the bean to get the message and then display it?
And how is the bean validation typically used? Only for Spring and Hibernate ,or for java EE in general?
Validation is used in JavaEE in general. Not only in Spring and Hibernate. Bean Validation is a JEE specification, marked as:
JSR-303 (v.1.0)
JSR-349 (v. 1.1)
JSR-380 (v. 2.0)
It works exacly as you mentioned in your question.

No converter found for return value of type: class com.spring.mvc.model.User]

Exception is here:
SEVERE: Servlet.service() for servlet [hello] in context with path [/Spring_MVC] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: No converter found for return value of type: class com.spring.mvc.model.User] with root cause
java.lang.IllegalArgumentException: No converter found for return value of type: class com.spring.mvc.model.User
Source code are below:
UserController.java
#Controller
#RequestMapping("/user")
public class UserController {
private Map<String,User> users = new HashMap <String, User>();
public UserController(){
users.put("wang", new User("wang","pwang","wang a bo","123"));
users.put("chen", new User("chen","pChen","Chen Lin","1e23"));
}
#RequestMapping(value="{userName}",method=RequestMethod.GET, params="json")
#ResponseBody
public User show(#PathVariable String userName) {
return users.get(userName);
}
}
User.java
public class User {
#NotEmpty(message="User Name not null!!!")
private String userName;
#Size(min=6,max=12,message="Password need 6 to 12 Character!!!")
private String passWord;
private String nickName;
#Email(message="Email Fromat invalide!!")
private String email;
public User(){
}
public User(String userName, String passWord, String nickName, String email) {
super();
this.userName = userName;
this.passWord = passWord;
this.nickName = nickName;
this.email = email;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Spring-4.3.5-Release
jackon-all-1.9.4.jar
I have used below jars to replaced jar jackon-all-1.9.4.jar. The problem has been resolved.
jackson-databind-2.5.0.jar
jackson-core-2.5.0.jar
jackson-annotations-2.5.0.jar

verify if an email is already in my database, using hibernate

I need to verify the email of the new user who would like to sign up in my application web. if the email is already in my database (mysql) so must don't accept this sign up and said said to him like: "your email already used".
Now I can save users in my database, but how to check them by his email for not repeat the inscription in my application web.
this is my Dao layer class :
public class UserDaoMysql implements UserDao {
private Session session;
private void openSession(){
SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
session = sessionFactory.openSession();
session.beginTransaction();
}
private void closeSession(){
session.getTransaction().commit();
session.close();
}
public void insert(User user) {
if(checkEmail(user)){
openSession();
User p = new User(user.getName(), user.getEmail(), user.getPassword());
session.save(p);
System.out.println("sauvegarde reussi");
closeSession();
}
}
public boolean checkEmail(User user){
return true;
}
}
this is my user bean :
#ManagedBean(name="user")
public class User {
private int id;
private String name;
private String email;
private String password;
private String confirmationPass;
// private image
public User() {
super();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getConfirmationPass() {
return confirmationPass;
}
public void setConfirmationPass(String confirmationPass) {
this.confirmationPass = confirmationPass;
}
public User(int id, String name, String email, String password,
String confirmationPass) {
super();
this.id = id;
this.name = name;
this.email = email;
this.password = password;
this.confirmationPass = confirmationPass;
}
public User(int id, String name, String email, String password) {
super();
this.id = id;
this.name = name;
this.email = email;
this.password = password;
}
public User(String name, String email, String password) {
super();
this.name = name;
this.email = email;
this.password = password;
}
#Override
public String toString() {
return "User [id=" + id + ", Name=" + name + ", email=" + email
+ ", password=" + password + "]";
}
public void save(){
UserBusiness userBusiness = new UserBusinessImp();
userBusiness.add(new User(name, email,password));
}
}
And I created a table "user" in my database.
Maybe there is an annotation which can help us to specify the email property as an unique one or something else.
What you can do is create a unique key on your email column in your table. After that, decorate your field using #Column(unique=true), that will indicate to Hibernate that this field has a unique key.
Also, be careful with your annotations. This is unrelated to your problem, but #ManagedBean marks the class as a bean able to interact with the view in JSF. Probably you want/need to use #Entity instead.

check if an email in my database while sign up, using hibernate

I am programming an IHM for sign up the users, I need to check if this user is already in database(mysql), checking by his email . can you help me please.
I can save my user now but how to check if this user by his email
this is my Dao layer class :
public class UserDaoMysql implements UserDao {
private Session session;
private void openSession(){
SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
session = sessionFactory.openSession();
session.beginTransaction();
}
private void closeSession(){
session.getTransaction().commit();
session.close();
}
public void insert(User user) {
if(checkEmail(user)){
openSession();
User p = new User(user.getName(), user.getEmail(), user.getPassword());
session.save(p);
System.out.println("sauvegarde reussi");
closeSession();
}
}
public boolean checkEmail(User user){
return true;
}
}
this is my user bean :
#ManagedBean(name="user")
public class User {
private int id;
private String name;
private String email;
private String password;
private String confirmationPass;
// private image
public User() {
super();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getConfirmationPass() {
return confirmationPass;
}
public void setConfirmationPass(String confirmationPass) {
this.confirmationPass = confirmationPass;
}
public User(int id, String name, String email, String password,
String confirmationPass) {
super();
this.id = id;
this.name = name;
this.email = email;
this.password = password;
this.confirmationPass = confirmationPass;
}
public User(int id, String name, String email, String password) {
super();
this.id = id;
this.name = name;
this.email = email;
this.password = password;
}
public User(String name, String email, String password) {
super();
this.name = name;
this.email = email;
this.password = password;
}
#Override
public String toString() {
return "User [id=" + id + ", Name=" + name + ", email=" + email
+ ", password=" + password + "]";
}
public void save(){
UserBusiness userBusiness = new UserBusinessImp();
userBusiness.add(new User(name, email,password));
}
}
And I have a table user in my database.
thanks for your help in advance
I would use NamedQuery for this. Define named query in your User entity like this:
...
#NamedQueries({
#NamedQuery(name = "User.findByEmail",
query = "SELECT u FROM User u WHERE u.email = :email")})
#ManagedBean(name="user")
public class User {
...
And then add method like this to your DAO
public List<User> getUsersByEmail(String email){
openSession();
Session session;
Query query = session.getNamedQuery("User.findByEmail");
query.setString("email", email);
Lis<Users> users = query.list();
closeSession();
return users;
}
This method is little bit more generic you can make it more specific returning user count only.

Logging In With JSP Hibernate

I have a problem with Hibernate to make login process. All codes are perfectly correct in terms of syntax. NetBeans tell me that my code have no problem. However, when I run the web, and I test the login process, it doesn't reacting and the address is stucked on the doLogin.
All classes have been mapped correctly.
This is my problem: when I try to retrieve data, my code is stucked on a line.
on doLogin servlet (I use the template provided by NetBeans and just filling in my code on the try. Here's in brief:
Connect con = new Connect(); //my code is stucked on this line.
//I've done testing where's the cause of the stuck, and this line is the cause.
List logger = con.getLogin(username, password);
and to make it clear:
Connect.java
public class Connect {
Session sesi;
public Connect() {
sesi = HibernateUtil.getSessionFactory().openSession();
}
public List getLogin(String username, String password){
return sesi.createQuery("from MsUser WHERE username = '"+username+"' and password = '"+password+"'").list();
}
}
and since that query is HQL, here is the MsUser class:
public class MsUser {
public MsUser() {
}
private int userID;
private String username;
private String firstname;
private String lastname;
private String email;
private String password;
private String gender;
private String address;
private String phone;
private String photo;
public MsUser(int userID, String username, String firstname, String lastname, String email, String password, String gender, String address, String phone, String photo) {
this.userID = userID;
this.username = username;
this.firstname = firstname;
this.lastname = lastname;
this.email = email;
this.password = password;
this.gender = gender;
this.address = address;
this.phone = phone;
this.photo = photo;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getPhoto() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
public int getUserID() {
return userID;
}
public void setUserID(int userID) {
this.userID = userID;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
please help. But I suspect on Connect's constructor as the main cause. Anybody can suggest or fix or tell me what causing me this.
appendix:
HibernateUtil.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package Controller;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.SessionFactory;
/**
* Hibernate Utility class with a convenient method to get Session Factory
* object.
*
* #author Ginanjar
*/
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
// Create the SessionFactory from standard (hibernate.cfg.xml)
// config file.
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
} catch (Throwable ex) {
// Log the exception.
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
You can try following code in your hibernateUtil.java file:
SessionFactory factory = new Configuration().configure().buildSessionFactory();
session = factory.openSession();
String query = "select reg.username,reg.password from MsUser as reg where reg.username='" + username + "' and reg.password='" + password + "'";
Query DBquery = session.createQuery(query);
for (Iterator it = DBquery.iterate(); it.hasNext();) { it.next();
count++;
}
System.out.println("Total rows: " + count);
if (count == 1) {
return true;
} else {
return false;
}
}

Categories

Resources