-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Hi guys,
I need to integrate JPA+Hibernate into my ZK-webapp but it wont really work that well. When a user points to webroot, he
will be asked to login. he provides a loginname and passwort, user validation is done via db-call. this is
how it looks:
public static User validUser(String name, String pw){ Session session = (Session) JpaUtil.getEntityManager().getDelegate(); session.beginTransaction(); Criteria crit = session.createCriteria(Benutzer.class) .add(Restrictions.and(Restrictions.eq("loginname", name),Restrictions.eq("passwort", pw))); User b = (User) crit.uniqueResult(); session.getTransaction().commit(); session.close(); }
INFO: EntityManagerFactory for: customer is created
INFO: EntityManagerFactory for: customer is created
in my zk.xml i made the entry for resolving the persistence-unit name that the name must not be provided every time via "...getEntityManager("customer")..."
<zk> <preference> <name>JpaUtil.PersistenceUnitName</name> <value>customer</value> </preference> ... </zk>
how should i open a session and process a request? i already read the provided smalltalk article "Hibernate + ZK", but that dont
handles jpa-integration :(
i know, that with the code printed above, i made a session per request... i would be highly appreciated if someone gives me a code snippet or a good explanation how to handle this problem...
thanks in advance
This looks like a typical Hibernate + ZK "ThreadLocal" issue. Let's do some experiments first. In your WEB-INF/zk.xml, specify this to disable the ZK event thread mechanism so there is no ThreadLocal issue. See if this solve your issue.
<system-config>
<disable-event-thread/>
</system-config>
And please provide your persistence.xml regarding the entitymanager so we have more information.
hi!
i integrate the code above in my zk.xml but there arent any changes... for every db-call the logger says:
16.07.2008 09:46:41 org.zkoss.zkplus.jpa.JpaUtil createEntityManagerFactory:250 INFO: EntityManagerFactory for: customer is created
here is my persistence.xml
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence" version="1.0"> <persistence-unit name="customer"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/> <property name="hibernate.hbm2ddl.auto" value="update"/> <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/> <property name="hibernate.connection.username" value="sa"/> <property name="hibernate.connection.password" value=""/> <property name="hibernate.connection.url" value="jdbc:hsqldb:hsql://localhost/customer"/> </properties> </persistence-unit> </persistence>
EDIT:
by adding the lines you provided, some code isn't executed...
scenario: user clicks on logout, die following event, "onLogout" is fired:
window.addEventListener("onLogout", new EventListener() { public void onEvent(Event event) throws Exception { // do logout, redirect to login-page int state = Messagebox.show("Wollen Sie sich abmelden?", "Info", Messagebox.OK | Messagebox.CANCEL, Messagebox.EXCLAMATION); if (state == Messagebox.OK) { Executions.sendRedirect("login.zul"); Sessions.getCurrent().invalidate(); } } });
EDIT 2:
by providing another peristence provider, "toplink", the db-calls are 10 times faster compared to the hibernate-provider... however, the disadvantage is that i cannot use the criteria api provided by hibernate...
heres the persistence.xml with toplink-provider:
<?xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence"> <persistence-unit name="customer" transaction-type="RESOURCE_LOCAL"> <provider>oracle.toplink.essentials.PersistenceProvider</provider> <exclude-unlisted-classes>false</exclude-unlisted-classes> <properties> <property name="toplink.jdbc.user" value="sa"/> <property name="toplink.jdbc.password" value=""/> <property name="toplink.jdbc.url" value="jdbc:hsqldb:hsql://localhost/pipe"/> <property name="toplink.jdbc.driver" value="org.hsqldb.jdbcDriver"/> <property name="toplink.platform.class.name" value="oracle.toplink.essentials.platform.database.HSQLPlatform"/> </properties> </persistence-unit> </persistence>
The repeat created EntityManagerFactory is a bug. Please follow
http://sourceforge.net/tracker/index.php?func=detail&aid=2020454&group_id=152762&atid=785191
/henri
As for the Messagebox.show(...) issue, the behavior is "expected". The ZK event thread mechanism is the base of the "modal window" (including Messagebox). The <disable-event-thread/> disable the event thread mechanism and the Messagebox.show() will not work as it was. For a discussion, please see this smalltalk:
thanks for your answer. is there any workaround for solving this problem? i must use jpa (because i annoted all my classes and there is "no way back") and i would prefer the hibernate session schema because i can use the criteria-api...
do you have any idea why the hibernate-provider is 10 times slower to db-calls than the toplink-provider?
The bug is fixed and shall be release in 3.0.7. Or if you are in a hurry you can write your own utility to handle the case. It is really simple.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("customer"); Executions.getCurrent().getDesktop().getWebApp.setAttribute("customer", emf);
create and cache the emf in WebApp attributes map.
EntityManager em = factory.createEntityManager() Executions.getCurrent().setAttribute("customer-em", em);
Then within an Execution, you always get the same EntityManager.
Executions.getCurrent() will change for each HttpRequest so you don't have to worry about memory free issue.
/henri
Hi Henrichen, thanks for solving this problem :)
Just one another question, how can i "load" the entitymanagerfactory on startup? now, i create the factory on the first request on server. but i want to instantiate the factory on startup. how can i do this? is there some entry needed in zk.xml?
Thanks for your help :)
Asked: 2008-07-15 15:04:19 +0800
Seen: 332 times
Last updated: Jul 20 '08