-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 21 posts ]  Go to page Previous  1, 2
Author Message
 Post subject: Re: Hibernate with JOTM on Tomcat - issues with Commit and Rollb
PostPosted: Thu Apr 15, 2010 1:36 pm 
Newbie

Joined: Tue Apr 13, 2010 3:37 am
Posts: 9
thanks. I am using your examples now.

The issue I face is that I am unable to bind to global JNDI in Tomcat.

Code:
jndiContext.bind("java:/UTx", userTransaction);


I get a javax.naming.NamingException: Context is read only. I understand that Tomcat supports only read-only JNDI.

When I try local JNDI binding:
Code:
jndiContext.bind("jtom/UTx", userTransaction);


I get a Hibernate Exception: Current Transaction Not available.

Have you tried this in a Tomcat environment?


Top
 Profile  
 
 Post subject: Re: Hibernate with JOTM on Tomcat - issues with Commit and Rollb
PostPosted: Fri Apr 16, 2010 5:16 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Quote:
I get a javax.naming.NamingException: Context is read only. I understand that Tomcat supports only read-only JNDI.


In truth using my example in tomcat, I got the same exception as you.
There strangely happens a fallback to the default JNDI implementation when binding a object
when there is no InitialContextFactoryBuilder set explicitely.
I saw it debugging following code in InitialContext.class:

Code:
protected Context getURLOrDefaultInitCtx(String name)
   throws NamingException {
   if (NamingManager.hasInitialContextFactoryBuilder()) {
       return getDefaultInitCtx();   /// this would return the proper custom JNDI implementation
   }
   String scheme = getURLScheme(name);
   if (scheme != null) {
       Context ctx = NamingManager.getURLContext(scheme, myProps);
       if (ctx != null) {
      return ctx;   /// this apparently returns a default JNDI implementation, which may be different as the one already initialized
      ...


I'm just working on a tomcat jta-example which gets rid of this problem by setting an own custom InitialContextFactoryBuilder.
As soon I have completed it and tested, I will give you the source ...


Top
 Profile  
 
 Post subject: Re: Hibernate with JOTM on Tomcat - issues with Commit and Rollb
PostPosted: Fri Apr 16, 2010 6:21 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Hi mavericjr,

now I was able to make the servlet sucessfully run under tomcat (version 6) with hibernate using JTA.
This time I used a custom local JNDI-implementation, so I need no any jboss library anymore
and I get rid of all serialization problems.
I also tested the commit and rollback functionality and it works correctly (the servlet test this).
See here the sources:

The servlet JTAHibernateServlet.java :

Code:
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.naming.spi.InitialContextFactory;
import javax.naming.spi.InitialContextFactoryBuilder;
import javax.naming.spi.NamingManager;
import javax.persistence.EntityManager;
import javax.persistence.Persistence;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.UserTransaction;

import org.enhydra.jdbc.standard.StandardXADataSource;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.ejb.HibernateEntityManagerFactory;
import org.hibernate.transaction.JOTMTransactionManagerLookup;
import org.objectweb.jotm.Jotm;
import org.objectweb.transaction.jta.TMService;

public class JTAHibernateServlet extends HttpServlet implements InitialContextFactoryBuilder {

   static JOTMTransactionManagerLookup _ml = new JOTMTransactionManagerLookup();
   static LocalContext _localCtx = null;

   public static class ExtendedXADataSource extends StandardXADataSource { // XAPOOL
      @Override
      public Connection getConnection() throws SQLException {
         // Accoding to Enhydra doku, here we must return the connection of
         // our XAConnection
         // see
         // http://cvs.forge.objectweb.org/cgi-bin/viewcvs.cgi/xapool/xapool/examples/xapooldatasource/DatabaseHelper.java?sortby=rev
         return super.getXAConnection().getConnection();
      }
   }


   public void doGet(HttpServletRequest request, HttpServletResponse response)
         throws IOException, ServletException {
      response.setContentType("text/html");
      PrintWriter out = response.getWriter();
      out.println("<html>");
      out.println("<head>");
      out.println("<title>Hello World!</title>");
      out.println("</head>");
      out.println("<body>");
      out
            .println("<h1>Hello world, here a hibernate jta example servlet!</h1>");

      try {
         Properties props = new Properties();
         if (!NamingManager.hasInitialContextFactoryBuilder())
            NamingManager.setInitialContextFactoryBuilder(this);
           
         InitialContext jndiCtx = new InitialContext(props);
         
         /* startup JOTM */
         TMService jotm = new Jotm(true, false);
         jotm.getUserTransaction().setTransactionTimeout(36000);
         // XAPOOL
         ExtendedXADataSource xads = new ExtendedXADataSource();
         xads.setDriverName("org.hsqldb.jdbcDriver");
         //xads.setDriverName("com.p6spy.engine.spy.P6SpyDriver");
         xads.setUrl("jdbc:hsqldb:hsql://localhost");
         xads.setTransactionManager(jotm.getTransactionManager());
         jndiCtx.bind("java:/MyDatasource", xads);

         

         
         jndiCtx
               .bind("java:comp/UserTransaction", jotm.getUserTransaction()); // this is needed by hibernates JTATransactionFactory

         HibernateEntityManagerFactory emf = (HibernateEntityManagerFactory) Persistence
               .createEntityManagerFactory("helloworld");
         UserTransaction userTransaction = jotm.getUserTransaction();
         SessionFactory sf = emf.getSessionFactory();

         userTransaction.begin();
         EntityManager em = emf.createEntityManager();

         Session session = (Session) em.getDelegate(); // sf.getCurrentSession();
          A a = new A();
          a.name= "firstvalue";
          session.save(a);
          session.flush();
          Serializable id = session.getIdentifier(a);
          out.println("<br>Created and flushed instance a with id : "
          + a.oid + "  a.name set to:" + a.name);
          out.println("<br>Calling userTransaction.commit() (Please check if the commit is effectively executed!)");
          userTransaction.commit();
                    
          userTransaction.begin();
          session = sf.openSession();
          A a1 = (A) session.get(A.class, id);
          out.print("<br>Should retrieve commited instance: " + a1.name);
          a = new A();
          a.name= "secondrecord";
          session.save(a);
          session.flush();
          id = session.getIdentifier(a);
         
          out.println("<br><br><br>Created and flushed instance a with id : "
          + a.oid + "  a.name set to:" + a.name);
          out.println("<br>Calling userTransaction.rollback()");
          userTransaction.rollback();
          userTransaction.begin();
          session = sf.openSession();
          A a2 = (A) session.get(A.class, id);
          out.print("<br><br>Should not retrieve rollbacked instance (shall be null): " + a2);
          userTransaction.rollback();
         
         out.println("</body>");
         out.println("</html>");

      } catch (Exception r) {
         r.printStackTrace();
      }
   }

   @Override
   public InitialContextFactory createInitialContextFactory(
         Hashtable<?, ?> environment) throws NamingException {
      
      return new InitialContextFactory() {

         @Override
         public Context getInitialContext(Hashtable<?, ?> environment)
               throws NamingException {
            if (_localCtx == null)
            {
               _localCtx = new LocalContext();
            }
            return _localCtx;
         }
         
      };
   }
}



The custom local (scope = classloader) JNDI-Implementation
LocalContext.java:

Code:
import java.util.Hashtable;
import javax.naming.Binding;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NameClassPair;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.OperationNotSupportedException;



public class LocalContext implements Context {
   
   
   static Hashtable<String,Object> string_object = new Hashtable<String,Object>();
   
   @Override
   public Object addToEnvironment(String propName, Object propVal)
         throws NamingException {
      throw new OperationNotSupportedException();
      
   }

   @Override
   public void bind(Name name, Object obj) throws NamingException {
      string_object.put(name.toString(), obj);
   }

   @Override
   public void bind(String name, Object obj) throws NamingException {
      string_object.put(name, obj);
   }

   @Override
   public void close() throws NamingException {
      string_object.clear();
      
   }

   @Override
   public Name composeName(Name name, Name prefix) throws NamingException {
      throw new OperationNotSupportedException();
      
   }

   @Override
   public String composeName(String name, String prefix)
         throws NamingException {
      throw new OperationNotSupportedException();
      
   }

   @Override
   public Context createSubcontext(Name name) throws NamingException {
      throw new OperationNotSupportedException();
      
   }

   @Override
   public Context createSubcontext(String name) throws NamingException {
      throw new OperationNotSupportedException();
      
   }

   @Override
   public void destroySubcontext(Name name) throws NamingException {
      throw new OperationNotSupportedException();
      
   }

   @Override
   public void destroySubcontext(String name) throws NamingException {
      throw new OperationNotSupportedException();
      
   }

   @Override
   public Hashtable<?, ?> getEnvironment() throws NamingException {
      throw new OperationNotSupportedException();
      
   }

   @Override
   public String getNameInNamespace() throws NamingException {
      throw new OperationNotSupportedException();
      
   }

   @Override
   public NameParser getNameParser(Name name) throws NamingException {
      throw new OperationNotSupportedException();
      
   }

   @Override
   public NameParser getNameParser(String name) throws NamingException {
      throw new OperationNotSupportedException();
      
   }

   @Override
   public NamingEnumeration<NameClassPair> list(Name name)
         throws NamingException {
      throw new OperationNotSupportedException();
      
   }

   @Override
   public NamingEnumeration<NameClassPair> list(String name)
         throws NamingException {
      throw new OperationNotSupportedException();
      
   }

   @Override
   public NamingEnumeration<Binding> listBindings(Name name)
         throws NamingException {
      throw new OperationNotSupportedException();
      
   }

   @Override
   public NamingEnumeration<Binding> listBindings(String name)
         throws NamingException {
      throw new OperationNotSupportedException();
      
   }

   @Override
   public Object lookup(Name name) throws NamingException {
      return string_object.get(name.toString());
   }

   @Override
   public Object lookup(String name) throws NamingException {
      return string_object.get(name);
   }

   @Override
   public Object lookupLink(Name name) throws NamingException {
      throw new OperationNotSupportedException();
      
   }

   @Override
   public Object lookupLink(String name) throws NamingException {
      throw new OperationNotSupportedException();
      
   }

   @Override
   public void rebind(Name name, Object obj) throws NamingException {
      string_object.put(name.toString(), obj);
      
   }

   @Override
   public void rebind(String name, Object obj) throws NamingException {
      string_object.put(name, obj);
      
   }

   @Override
   public Object removeFromEnvironment(String propName) throws NamingException {
      throw new OperationNotSupportedException();
      
   }

   @Override
   public void rename(Name oldName, Name newName) throws NamingException {
      throw new OperationNotSupportedException();
      
   }

   @Override
   public void rename(String oldName, String newName) throws NamingException {
      throw new OperationNotSupportedException();
      
   }

   @Override
   public void unbind(Name name) throws NamingException {
      string_object.remove(name.toString());
   }

   @Override
   public void unbind(String name) throws NamingException {
      string_object.remove(name);
   }

}


My configuration (persistence.xml):

Code:
<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_1_0.xsd"  version="1.0">
  <persistence-unit name="helloworld" transaction-type="JTA">
      <jta-data-source>java:/MyDatasource</jta-data-source> 
      <properties>
     
        <property name="hibernate.hbm2ddl.auto" value = "create"/>
        <property name="hibernate.archive.autodetection" value="class, hbm"/>
        <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
           
     
   <property name="hibernate.current_session_context_class" value="org.hibernate.context.JTASessionContext"/>
   <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory"/>
         
         <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JOTMTransactionManagerLookup"/> 
           
      </properties>
   </persistence-unit>
</persistence>



My test persistent class A.java:

Code:
@Entity
public class A {
    @Id @GeneratedValue(strategy = GenerationType.TABLE)
    public long oid;
       
    @Column
    @NaturalId (mutable = false)
    public String name;
}


Top
 Profile  
 
 Post subject: Re: Hibernate with JOTM on Tomcat - issues with Commit and Rollb
PostPosted: Fri Apr 16, 2010 8:48 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Hi mavericjr,

according JOTM documentation it should also work using the default JNDI of tomcat.
See http://jotm.objectweb.org/current/jotm/doc/howto-tomcat-jotm.html

As JNDI of tomcat is read-only, only Tomcat itself has the right to bind object to JNDI.
For Hibernate it is therefore not enough to declare the datasource as Resource in Context.xml.
You must also declare the UserTransaction as Resource in Context.xml as described in the linked article,
because Hibernate with JTA expects the UserTransaction to be already bound on JNDI.


Furthermore (also mentioned in the linked article) you must NOT use JOTM's jndi wrapper CAROL:
Quote:
# do not use CAROL JNDI wrapper
carol.start.jndi=false


Therefore in this context it is also wrong to specify
Code:
<property name="hibernate.jndi.class">org.ow2.carol.jndi.spi.MultiOrbInitialContextFactory</property>


Finally it is important to couple the XADatasoure with your TransactionManager,
so in your servlet code, before you begin to work with hibernate, you probably have to set the proper transaction Manager on the datasource:

Code:
InitialContext jndiCtx = new InitialContext();
MysqlXADataSource datasource = (MysqlXADataSource) jndiCtx.lookup("jdbc/LocalYouDB");
datasource.setTransactionManager(jotm.getTransactionManager());


Top
 Profile  
 
 Post subject: Re: Hibernate with JOTM on Tomcat - issues with Commit and Rollb
PostPosted: Fri Apr 16, 2010 1:47 pm 
Newbie

Joined: Tue Apr 13, 2010 3:37 am
Posts: 9
Both the solutions work :) I think the second solution in more cleaner and we use it.
Thanks a lot for all the advice and time.

You have a great vacation.


Top
 Profile  
 
 Post subject: Re: Hibernate with JOTM on Tomcat - issues with Commit and Rollb
PostPosted: Thu Oct 16, 2014 12:28 pm 
Newbie

Joined: Thu Oct 16, 2014 12:24 pm
Posts: 1
We are working on a similar implementation and facing issues.

Can you please share your final context.xml, persistence.xml and the servlet which worked for you?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 21 posts ]  Go to page Previous  1, 2

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.