I have the following java class to connect and query MySQL database using JPA:
public class UserEntityManager {
private EntityManagerFactory emf;
private EntityManager em;
private EntityTransaction tx;
public UserEntityManager() {
emf = Persistence.createEntityManagerFactory("OmegaThingsPU");
em = emf.createEntityManager();
tx = em.getTransaction();
}
public User getUser(String username, String password) {
Query query = em.createQuery("SELECT u FROM User u "
+ "WHERE u.userUsername = :userUsername "
+ "AND u.userPassword = :userPassword");
query.setParameter("userUsername", username);
query.setParameter("userPassword", password);
User user;
try {
user = (User) query.getSingleResult();
em.close();
emf.close();
return user;
} catch (Exception ex) {
System.out.println("Exception ****************** ");
System.out.println(ex.toString());
em.close();
emf.close();
return null;
}
}
}
I'm always getting this exception:
java.lang.ClassCastException: com.omegathings.persistant.User cannot be cast to com.omegathings.persistant.User
I tried getResultList().get(0), but it didn't work also, what I'm missing here?
UPDATE:
Restarting the glassfish server (Version 4.1) will solve the problem temporary, but then on modifying the code and redeploying the application, I'm getting the exception again.
UPDATE:
It seems that on redeploying the application I'm getting 2 different class loaders as the following:
WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)
WebappClassLoader (delegate=true)
UPDATE:
Printing out the parent of the 2 above classloaders results in the following:
org.glassfish.internal.api.DelegatingClassLoader#5b11b82d
org.glassfish.internal.api.DelegatingClassLoader#5b11b82d
As you can see, at first deployment, the Ids are identical.
Now on the second deployment I got:
org.glassfish.internal.api.DelegatingClassLoader#57c83b1d
org.glassfish.internal.api.DelegatingClassLoader#5b11b82d
Where 2 parents have a different Ids, I'm not sure if this will help in solving my problem.
Finally I figure out the problem after many, many tests....
The problem is in the following websocket code:
#ServerEndpoint("/endpoint/{authentication}")
public class WSManager {
UserEntityManager userEntityManager = new UserEntityManager();
#OnOpen
public void onOpen(Session session, #PathParam("authentication") String authString) {
User user = new User();
user = (User) userEntityManager.getUser(parameter[0]);}
The problem is instantiating UserEntityManager class outside any of the following websocket class methods (onOpen, onMessage, onError, onClose).
Just moving the instantiation inside onOpen method will solve the problem.
I can't elaborate on the reason of such behavior, so, may some experts do.
Related
I working with PostgreSQL in multithread mode by Hibernate sessions. Init:
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="hibernate.current_session_context_class">thread</property>
(other strings is connection URL and entity xml describe))
HibernateUtil:
public class HibernateUtil {
private static SessionFactory sessionFactory;
static {
try {
Configuration configuration = new Configuration();
configuration.configure();
sessionFactory = configuration.buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static Session getSession() {
return sessionFactory.getCurrentSession();
}
public static void close() {
sessionFactory.close();
}
public static void setSessionFactory(SessionFactory factory) {
sessionFactory = factory;
}
}
All CRUD actions with Entities i do in separate class, where every action execute in one transaction.
public class SessionService {
public static <T> T get(Class<T> classvar, int id) {
Session session = HibernateUtil.getSession();
session.beginTransaction();
T result = session.get(classvar, id);
session.getTransaction().commit();
return result;
}
// Some other code
public static void update(Object obj) {
Session session = HibernateUtil.getSession();
session.beginTransaction();
session.update(obj);
session.getTransaction().commit();
}
}
There is no problems with multithreading work (or i not see it). But, some time ago i seen strange bug. I got one record from db by SessionService.get(Entity.class, 1). Change one field of this entity and save it by SessionService.update(entity). Update was successfull done without exceptions (logging approved). But changes not seen in database. In runtime entity has this changes, but not in db. I wait some time (for flush and others) but nothing changed.
Tried to repeat bug - all good, bug not found. In one day i catch this bug on production server with 19 objects from 200, but in other days i not seen this bug.
Last importan moment: i dont catched this bug with other entities (or i dont see them).
What may be reason of it? May be better use entity manager instead sessions?
Can you please post the entire hibernate.cfg.xml file (delete the username and password of course).
Also are you 100% sure that you do not get an error like (wild guess) :
A different object with the same identifier value was already associated with the session ?
There are errors while running Hibernate, that literary flashes in the console for half a second when running queries.
Had this problem a while back.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I'm trying to create a Java application that will run on a hypothetical client machine, where members of staff can both view or add customer details from a local MySQL database.
I'm trying to use JPA to do so, with query methods being in this form:
public class DataManagerImpl implements DataManager{
#PersistenceContext
private EntityManager em;
public List<Customer> AllCustomers(){
TypedQuery<Customer> query = em.createNamedQuery("Customer.findAll", Customer.class);
return query.getResultList();
} }
I've got a DBConnection class:
public class MyDBConn implements DBConnectivity {
#Resource(mappedName="jdbc:mysql://localhost:3306/solsoft_DB") DataSource dataSource;
Connection myConn = null;
public Connection open_Connection() {
String user = "root";
String pass = "password";
try {
Class.forName("com.mysql.jdbc.Driver");
myConn = dataSource.getConnection(user, pass);
return myConn;
} catch (Exception exc) {
exc.printStackTrace();
return myConn;
}
}}
And then in my main method:
DataManagerImpl dm = new DataManagerImpl();
List<Customer> allCustomers = dm.AllCustomers();
for(Customer c : allCustomers){
String cust = "" + c.getForename() + " " + c.getSurname();
System.out.println(cust);
}
I'd really appreciate if anyone could point my in the right direction on how to actually go about getting some information from the DB using JPA in this way.
The application will be running in a server? What server?
Or is an standalone application?
My guess (the best I can do as there are many things not pointed in the question) is that you are trying to supply the connection that PersistenceContext should use.
If its like this and you are using JPA you should register an EntityManagerFactory with the required properties for connection and get your PersistenceContext from that factory. (See an example here)
Another way to go would be to edit your persistence.xml file defining this properties inside the file like this and just let your context handle the logic for database connection.
Please Help:
Below error when I tried to add details to tables using hibernate:
NullPointerException
org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge.nextTimestamp(RegionFactoryCacheProviderBridge.java:93)
SessionFactoryImpl.openSession(SessionFactoryImpl.java:639)
SessionFactoryImpl.openSession(SessionFactoryImpl.java:648)
com.package1.service.AuthenticateUser.addUser(AuthenticateUser.java:32)
com.package1.controllers.LoginServlet.doPost(LoginServlet.java:68)
AuthenticateUser:
public class AuthenticateUser {
public void addUser(String uname, String uemail, String usrnme,
String upass) {
Session session = factory.openSession(); //Line No:32
Transaction txn = session.beginTransaction();
user.setName(uname);
user.setEmail(uemail);
user.setUsrname(usrnme);
user.setPassword(upass);
txn.commit();
session.save(user);
session.close();
factory.close();
}
private static SessionFactory factory = HibernateSessionManager
.getSessionFactory();
private User user = new User();
}
In LoginServlet I call
authenticateUser.addUser("abcdef", "abcdef","abcdef", "abcdef");
You are closing the factory object, so attempting to open a session with it has chances to cause such a crash (on next call).
Remove this line :
factory.close();
Try to convert this order:
txn.commit();
session.save(user);
Like this:
session.save(user);
txn.commit();
this error ocurrs when you try to create an EntityManager with a closed EntityManagerFactory.
So, the recomandation is,
EntityManagers must be ephimerals *create and close only in the scope of the transaction.
EntityManagerFactory must be application scoped.
NullPointerException
org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge.nextTimestamp(RegionFactoryCacheProviderBridge.java:93)
I am fully testing an entity on my unit test, and almost everything worked so far: create, update, list. However, when I try to delete a record, it is not getting deleted. Here is the code I am using:
public void delete (Integer id) {
// This doesnt work even though I know user is set and id is not null
User user = find(id);
getSession().delete(user);
// This will work
// Query query = getSession().createSQLQuery("DELETE FROM users WHERE id = " + id);
// query.executeUpdate();
}
private Session getSession() {
if (session == null) {
try {
session = SessionFactoryUtils.getSession(sessionFactory, Boolean.TRUE);
TransactionSynchronizationManager.bindResource(session.getSessionFactory(), new SessionHolder(session));
} catch (Exception e) {
session = SessionFactoryUtils.getSession(sessionFactory, Boolean.FALSE);
}
}
return session;
}
If I execute the query directly it works but using the delete() method doesnt. I think it may be related to committing the transaction but I already tried something like that and no luck. Any ideas?
I found the problem with this one.
First, find() method was evicting my user model, and probably taking it out of the session.
After delete(), I also needed to session.flush()
I m using glassfish v2 and persistence in a web application.
I m calling persistence codes using a normal java class file inside a web Application
I can select easily using this code: -
#PersistenceUnit
public EntityManagerFactory emf;
EntityManager em;
public List fname (String id) {
String fname = null;
List persons = null;
//private PersistenceManagerFactory persistenceManagerFactory;
try {
emf = Persistence.createEntityManagerFactory("WebApplicationSecurityPU");
em = emf.createEntityManager();
persons = em.createQuery("select r from Roleuser r").getResultList();
int i=0;
for (i=0;i<persons.size(); i++)
System.out.println("Testing n "+ i +" " + persons.get(i));
} catch(Exception e) {
System.out.println("" + e);
}
finally {
if(em != null) {
em.close();
}
}
return persons;
}
I want to update using JTA as the persistence.xml file has
transaction-type="JTA"
When i try using update using this code i get a nullPointerException without any traces in the log
#PersistenceUnit
public EntityManagerFactory emf;
EntityManager em;
Context context;
#Resource
private UserTransaction utx;
public List fname (String id) {
String fname = null;
List persons = null;
try {
emf = Persistence.createEntityManagerFactory("WebApplicationSecurityPU");
utx.begin();
em = emf.createEntityManager();
int m = em.createQuery("update Roleuser r set r.firstName = 'Jignesh I' where r.userID=9").executeUpdate();
utx.commit();
} catch(Exception e) {
System.out.println("" + e);
}
finally {
if(em != null) {
em.close();
}
}
return persons;
}
Any help
Thanks
Pradyut
Perhaps your bean isn't managed - i.e. it's not part of any context (spring, EJB). How are you creating your object?
You really should not call createEntityManager() - inject one using #PersistenceContext
You must be absolutely sure you need JTA before using it.
You seem to be using PersistenceUnit, but then re-assign the etm - I'd suggest drop both and see p2 above.
If you are not using any dependecy injection at all, then drop all the annotations, retain the current code, and type:
em.getTransaction().begin();
...
em.getTransaction().commit();
(and define RESOURCE_LOCAL in your persistence.xml. You really don't need JTA)
well the code should be without any nightmares...(atleast for me in glassfish)
with the persistence.xml having
<persistence-unit name="WebApplicationSecurityPU" transaction-type="RESOURCE_LOCAL">
the code
#PersistenceUnit
public EntityManagerFactory emf;
public EntityManager em;
public EntityManager getEm() {
emf = Persistence.createEntityManagerFactory("WebApplicationSecurityPU");
em = emf.createEntityManager();
return em;
}
public List fname (String id) {
String fname = null;
List persons = null;
try {
System.out.println("test");
em = this.getEm();
em.getTransaction().begin();
int m = em.createQuery("update Roleuser r set r.firstName = 'Jignesh H' where r.userID=9").executeUpdate();
em.getTransaction().commit();
} catch(Exception e) {
System.out.println("" + e);
}
finally {
if(em != null) {
em.close();
}
}
return persons;
}
Any improvements are welcome...(actually needed...)
(How to go about using #PersistenceContext)
Thanks
Pradyut
Your "normal" class is very likely not a managed component i.e. a class whose life cycle is managed by the container (like Servlets, Servlet Filters, JSP tag handlers, JSF Managed Beans, ...) and can't benefit from resource injection1.
So neither the UserTransaction nor the EntityManagerFactory are injected here, hence the NullPointerException.
Honestly, you should try to use a container managed EntityManager, this would make your code less messy. If you cannot get it injected, get it via a JNDI lookup. See the resource below.
1 Have a look at Web Tier to Go With Java EE 5: A Look at Resource Injection for a nice overview of what can be injected, and where.
Resources
How to use EntityManager API in web module
References
JPA 1.0 specification
Section 5.2 "Obtaining an Entity Manager"
Section 5.6 "Container-managed Persistence Contexts"